将MacAddress转换为Java中的本地IPv6链接

时间:2019-05-14 14:11:38

标签: java mac-address link-local

我需要将Mac地址转换为IPv6 Link本地地址。 此link-local IPv6是从NIC’s mac地址推断出来的。 转换过程如下。

  1. 获取mac地址:例如52:74:f2:b1:a8:7f

  2. 将ff:fe放在中间:52:74:f2:ff:fe:b1:a8:7f

  3. 重新格式化为IPv6表示法5274:f2ff:feb1:a87f

  4. 将第一个八位位组从十六进制转换为二进制:52 -> 01010010

  5. 将索引6的位取反(从0开始计数):01010010 -> 01010000

  6. 将八位位组转换回十六进制:01010000 -> 50

  7. 用新计算的一个替换第一个八位位组:5074:f2ff:feb1:a87f

  8. 在链接本地前缀之前:fe80::5074:f2ff:feb1:a87f

这似乎是许多特定的字符串操作以及数字系统之间的转换。 我一直在寻找Java中的实用程序类,该实用程序类可以帮助我以更有效的方式进行操作。 我看到Java在InetAddress中有方法来确定所讨论的地址是否是本地链接。

2 个答案:

答案 0 :(得分:1)

IPAddress Java library具有执行此操作的方法。免责声明:我是该库的项目经理。

以下是使用示例MAC地址52:74:f2:b1:a8:7f的示例代码

   String str = "52:74:f2:b1:a8:7f";
   try {
      MACAddress mac = new MACAddressString(str).toAddress();
      IPv6Address linkLocal = mac.toLinkLocalIPv6();
      System.out.println("converted " + mac + " to IPv6 link local " + linkLocal);
   } catch(AddressStringException e) {
      // handle invalid address string here
   }

输出为:

converted 52:74:f2:b1:a8:7f to IPv6 link local fe80::5074:f2ff:feb1:a87f

Wiki中有更多examples

答案 1 :(得分:0)

我尝试使用StringBuilder实现用于字符串操作的自定义生成器。希望对您有帮助。

自定义课程

public class Address  {
    @SuppressWarnings("unused")
    private static final long serialVersionUID = 1L;
    String ip;

    Address(String ip) {
        this.ip = ip;
    }

    boolean isLinkLocal() throws UnknownHostException{
        return getInet6Address().isLinkLocalAddress();
    }

    @SuppressWarnings("static-access")
    Inet6Address getInet6Address() throws UnknownHostException {
        return (Inet6Address) Inet6Address.getByName(getIp());
    }

    String getIp() {
        return this.ip;
    }
}

构建器

public class AddressBuilder {
    private String mac1;
    private String mac2;
    private String mac3;
    private String mac4;
    private String mac5;
    private String mac6;

    private String ipv6_2;
    private String ipv6_3;
    private String ipv6_4;

    private String ipv6;

    private static final String IPV6_1 = "fe80";
    private static final String FF_FE = "ff:fe";
    private static final String DOTS = "ff:fe";

    public AddressBuilder () { }

    AddressBuilder setMac(String mac){
        String[] splittedMac = mac.split(":");
        this.mac1 = splittedMac[0];
        this.mac2 = splittedMac[1];
        this.mac3 = splittedMac[2];
        this.mac4 = splittedMac[3];
        this.mac5 = splittedMac[4];
        this.mac6 = splittedMac[5];
        return this;
    }

    AddressBuilder throwFffeAndReformatToIPv6Notation() {
        StringBuilder sb = new StringBuilder();
        this.ipv6 = sb
            .append(mac1)
            .append(mac2)
            .append(DOTS)
            .append(mac3)
            .append(FF_FE)
            .append(mac4)
            .append(DOTS)
            .append(mac5)
            .append(mac6)
            .toString();
        String[] splittedIPv6 = this.ipv6.split(":");
        this.ipv6_2 = splittedIPv6[0];
        this.ipv6_3 = splittedIPv6[1];
        this.ipv6_4 = splittedIPv6[2];
        return this;
    }

    AddressBuilder convertFirstOctetFromHexToBinaryAndReplaceIt() {
        char[] binaryString = Integer.toBinaryString(Integer.parseInt(this.ipv6_2.substring(0, 2))).toCharArray();
        Integer binaryStringInverted = Integer.parseUnsignedInt(Character.toString(binaryString[5])) == 0 ? 1 : 0;
        binaryString[5] = binaryStringInverted.toString().toCharArray()[0];
        this.ipv6_2 = new String(binaryString);
        return this;
    }

    AddressBuilder prependLocalLinkPrefix() {
        StringBuilder sb = new StringBuilder();
        this.ipv6 = sb
            .append(IPV6_1)
            .append(DOTS)
            .append(ipv6_2)
            .append(DOTS)
            .append(ipv6_3)
            .append(DOTS)
            .append(ipv6_4)
            .toString();
        return this;
    }

    Address build(){
        return new Address(this.ipv6);
    }
}

使用示例

String mac = "52:74:f2:b1:a8:7f";    
AddressBuilder ad = new AddressBuilder();
Address address = ad
    .setMac(mac)
    .throwFffeAndReformatToIPv6Notation()
    .convertFirstOctetFromHexToBinaryAndReplaceIt()
    .prependLocalLinkPrefix()
    .build();
try {
    System.out.println("is Link local? "+address.isLinkLocal());
} catch (UnknownHostException uhe) {
    System.out.println("is Link local? no");
}