我需要将Mac地址转换为IPv6 Link
本地地址。
此link-local IPv6
是从NIC’s
mac地址推断出来的。
转换过程如下。
使用mac地址:例如52:74:f2:b1:a8:7f
将ff:fe放在中间:52:74:f2:ff:fe:b1:a8:7f
重新格式化为IPv6表示法5274:f2ff:feb1:a87f
将第一个八位位组从十六进制转换为二进制:52 -> 01010010
反转索引6的位(从0开始计数):01010010 -> 01010000
将八位位组转换回十六进制:01010000 -> 50
用新计算的第一个八位位组代替:5074:f2ff:feb1:a87f
在链接本地前缀之前:fe80::5074:f2ff:feb1:a87f
这似乎是许多数字系统之间特定的字符串操作和转换。
我一直在寻找Java中的实用程序类,该实用程序类可以帮助我以更有效的方式进行操作。
我看到Java在InetAddress
中有方法来确定所讨论的地址是否是本地链接。
最佳答案
我尝试使用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;
private static final String IPV6_1 = "FE80::";
private static final String FF_FE = "FF:FE";
private static final String DOTS = ":";
/**
* Constructor
*/
public AddressBuilder () { }
/**
* setMac
*
* @param mac
* @return
*/
private static final String LOG_MESSAGE_1 =
"MAC set to : {%s,%s,%s,%s,%s}";
public 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];
log(LOG_MESSAGE_1, splittedMac);
return this;
}
/**
* throwFffeAndReformatToIPv6Notation
*
* @return
*/
private static final String LOG_MESSAGE_2 =
"Throwing FFFE and reformat to IPV6 notation : %s";
public 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();
log(LOG_MESSAGE_2, this.ipv6);
return this;
}
/**
* convertFirstOctetFromHexToBinaryAndReplaceIt
*
* @return
*/
private static final String LOG_MESSAGE_3 =
"Convert 1st octet from hex to binary : %s -> %s";
private static final String LOG_MESSAGE_4 =
"Invert bit at 6th index : %s";
private static final String LOG_MESSAGE_5 =
"Convert this binary string to hex : %s";
private static final String LOG_MESSAGE_6 =
"Replace octet with the newly calculated one : %s";
public AddressBuilder convertFirstOctetFromHexToBinaryAndReplaceIt() {
String firstOctet = this.ipv6.substring(0, 2);
String binaryString = new BigInteger(firstOctet, 16).toString(2);
log(LOG_MESSAGE_3, firstOctet, binaryString);
char[] binaryCharArray = binaryString.toCharArray();
binaryCharArray[6] = Integer
.parseInt(Character.toString(binaryString.toCharArray()[6])) == 0
? '1' : '0';
binaryString = new String(binaryCharArray);
log(LOG_MESSAGE_4, binaryString);
String hex1stOctet = new BigInteger(binaryString, 2).toString(16);
log(LOG_MESSAGE_5, hex1stOctet);
this.ipv6 = hex1stOctet+this.ipv6.substring(2);
log(LOG_MESSAGE_6, this.ipv6);
return this;
}
/**
*
* prependLocalLinkPrefix
*
* @return
*/
private static final String LOG_MESSAGE_7 =
"Prepend link local prefix : %s";
AddressBuilder prependLocalLinkPrefix() {
this.ipv6 = (IPV6_1+this.ipv6).toUpperCase();
log(LOG_MESSAGE_7, this.ipv6);
return this;
}
/**
* build
*
* @return
*/
Address build() {
return new Address(this.ipv6);
}
/**
* log
*
* @param message
* @param strings
*/
private static void log(String message, String ...strings) {
System.out.println(String.format(message, strings));
}
}
使用例
public class App {
public static void main(String[] args) {
String mac = "CC:BE:59:B3:97:03";
AddressBuilder ad = new AddressBuilder();
Address address = ad
.setMac(mac)
.throwFffeAndReformatToIPv6Notation()
.convertFirstOctetFromHexToBinaryAndReplaceIt()
.prependLocalLinkPrefix()
.build();
try {
System.out.println("is Link local? "+address.isLinkLocal());
System.out.println("link local : "+address.getIp());
} catch (UnknownHostException uhe) {
System.out.println("is Link local? no");
}
}
}
输出量
MAC设置为:{CC,BE,59,B3,97}
抛出FFFE并重新格式化为IPV6表示法:CCBE:59FF:FEB3:9703
将第一个八位位组从十六进制转换为二进制:CC-> 11001100
第六索引的反转位:11001110
将此二进制字符串转换为十六进制:ce
用新计算的八位位组替换八位位组:ceBE:59FF:FEB3:9703
前缀链接本地前缀:FE80 :: CEBE:59FF:FEB3:9703
Link是本地的吗?真正
本地链接:FE80 :: CEBE:59FF:FEB3:9703
关于java - 将Mac地址转换为Java中的本地IPv6链接,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56132467/