从 MAC 地址递增十六进制字符串
Incrementing hexadecimal string from MAC Address
我正在尝试进行一些字符串操作。有没有一种方法可以在没有大量 if 语句的情况下做到这一点。
对于给定的 MAC 地址,我需要将最后一个值更改为 +1。例如:
84:1D:A2:B9:A3:D0 => Needs to change to: 84:1D:A2:B9:A3:D1
84:1D:A2:B9:A3:99 => Needs to change to: 84:1D:A2:B9:A3:A0
84:1D:A2:B9:A3:AF => Needs to change to: 84:1D:A2:B9:A3:B0
var _cnames = "84:8D:C7:BB:A3:F0";
var res = _cnames.slice(15, 17);
if(res[1] == "0" || res[1] == "1" || res[1] == "2" || res[1] == "3"
|| res[1] == "4" || res[1] == "5" || res[1] == "6" || res[1] == "7"
|| res[1] == "8" || res[1] == "A" || res[1] == "B" || res[1] == "C"
|| res[1] == "D" || res[1] == "E"){
res = res[0] + String.fromCharCode(res.charCodeAt(1) + 1);
}
if(res[1] == "F"){
if(res[0] == "9"){
res = "A0";
}else{
res = String.fromCharCode(res.charCodeAt(0) + 1) + "0";
}
}
if(res[1] == "9"){
res = res[0] + "A";
}
console.log(res);
这是我目前的解决方案,但效率不如我希望的那样。必须有更好的方法来解决这样的问题。
JS 中非 10 进制的数学
对此有一个非常简单的答案。函数 parseInt()
接受第二个参数,即传入值的基数。例如
parseInt("F0", 16) // Tells us that this is a base 16 (hex) number.
这将使我们转换为十进制。现在,数字类型的 toString()
方法也接受传出值的基数。所以如果我们把它放在一起看起来像这样。
(parseInt("F0", 16) + 1 ).toString(16) // returns f1
这取值 F0
,一个十六进制数字,将其转换为十进制加 1,然后 returns 返回一个十六进制字符串。
希望对您有所帮助!
编辑
为了更具体地回答您的问题,mac 地址的上下文是 00-FF,因此下面的内容将正确地用前导零填充,并使用模数 'wrap' 任何超过 FF 的数字回到 00 并再次向上。
("0"+ ((parseInt("FF", 16) + 1) % 256 ).toString(16)).substr(-2)
这是一个解决方案(不处理 FF
案例)
基本上是用parseInt
以16为基数转成数字,再用toString
以16为基数转为十六进制字符串
var _cnames = "84:8D:C7:BB:A3:F0";
var parts = _cnames.split(':');
var last = parts.pop();
var incremented = (parseInt(last,16) + 1).toString(16).toUpperCase().padStart(2,'0');
parts.push(incremented);
var updated = parts.join(':');
console.log(updated);
完整的解决方案
备注:
注意小于 8 的值
==> '04' +1 => '5'
,
并且需要添加 前导零 以获得正确的 MAC 地址
function nextMACaddress( MACaddress )
{
let hex = MACaddress.split(':').map(x=>parseInt(x,16))
plusOne(hex.length-1)
return hex.map(x=>('0'+x.toString(16).toUpperCase()).slice(-2)).join(':')
function plusOne(p) {
if (p<0) return
if (hex[p]==255) { hex[p]=0; plusOne(p-1) }
else { hex[p]++ }
}
}
console.log('84:1D:A2:B9:A3:D0 =>', nextMACaddress('84:1D:A2:B9:A3:D0') ) // 84:1D:A2:B9:A3:D1
console.log('84:1D:A2:B9:A3:99 =>', nextMACaddress('84:1D:A2:B9:A3:99') ) // 84:1D:A2:B9:A3:9A
console.log('84:1D:A2:B9:A3:AF =>', nextMACaddress('84:1D:A2:B9:A3:AF') ) // 84:1D:A2:B9:A3:B0
console.log('84:1D:A2:B9:A3:03 =>', nextMACaddress('84:1D:A2:B9:A3:03') ) // 84:1D:A2:B9:A3:04
console.log('84:1D:A2:FF:FF:FF =>', nextMACaddress('84:1D:A2:FF:FF:FF') ) // 84:1D:A3:00:00:00
console.log('FF:FF:FF:FF:FF:FF =>', nextMACaddress('FF:FF:FF:FF:FF:FF') ) // 00:00:00:00:00:00
您好,我对您的要求有点困惑:
- "For a given MAC address I need to change the last value to +1";所以你的意思是最后一个 "octet",最后一个冒号后面的最后两个字符?不是 非常 最后一个字符,也不是,至少在给出的几个答案中,比最后一个八位字节多?
- "84:1D:A2:B9:A3:99 => 需要更改为:84:1D:A2:B9:A3:A0" -- 我认为您在这里的十六进制数学可能不正确,将“99”结果加一在“9A”中不是 "A0"
- 最后,如果我对上面第一点的看法是正确的,我假设如果最后一个八位字节是“99”,你想回到“01”
(终于大声笑了,我可能错误地假设这些 macAddrs 在一个数组中,但它应该足够简单,可以从后面的 Array.map
方法中提取逻辑)
假设我对上面的内容是正确的,这里是我的简洁解决方案,它使用 ES2017 中的 padStart
,因此不受 IE 支持——注意我已经通过使用取消了拆分的需要(更简单?)切片, 受 IE
支持
const macAddrs = [
'84:1D:A2:B9:A3:D0',
'84:1D:A2:B9:A3:99',
'84:1D:A2:B9:A3:AF',
'84:1D:A2:B9:A3:FF'
];
const addrsIncr = macAddrs.map(addr => {
let addrPrefix = addr.slice(0, 15); // everything up to and including last colon
let modulusIncrLastOctet = (parseInt(addr.slice(15), 16) + 1) % 256; // converts FF to 01
return addrPrefix + modulusIncrLastOctet.toString(16).padStart(2, 0).toUpperCase();
});
console.log(addrsIncr);
输出:
[ '84:1D:A2:B9:A3:D1',
'84:1D:A2:B9:A3:9A',
'84:1D:A2:B9:A3:B0',
'84:1D:A2:B9:A3:00' ]
我正在尝试进行一些字符串操作。有没有一种方法可以在没有大量 if 语句的情况下做到这一点。
对于给定的 MAC 地址,我需要将最后一个值更改为 +1。例如:
84:1D:A2:B9:A3:D0 => Needs to change to: 84:1D:A2:B9:A3:D1
84:1D:A2:B9:A3:99 => Needs to change to: 84:1D:A2:B9:A3:A0
84:1D:A2:B9:A3:AF => Needs to change to: 84:1D:A2:B9:A3:B0
var _cnames = "84:8D:C7:BB:A3:F0";
var res = _cnames.slice(15, 17);
if(res[1] == "0" || res[1] == "1" || res[1] == "2" || res[1] == "3"
|| res[1] == "4" || res[1] == "5" || res[1] == "6" || res[1] == "7"
|| res[1] == "8" || res[1] == "A" || res[1] == "B" || res[1] == "C"
|| res[1] == "D" || res[1] == "E"){
res = res[0] + String.fromCharCode(res.charCodeAt(1) + 1);
}
if(res[1] == "F"){
if(res[0] == "9"){
res = "A0";
}else{
res = String.fromCharCode(res.charCodeAt(0) + 1) + "0";
}
}
if(res[1] == "9"){
res = res[0] + "A";
}
console.log(res);
这是我目前的解决方案,但效率不如我希望的那样。必须有更好的方法来解决这样的问题。
JS 中非 10 进制的数学
对此有一个非常简单的答案。函数 parseInt()
接受第二个参数,即传入值的基数。例如
parseInt("F0", 16) // Tells us that this is a base 16 (hex) number.
这将使我们转换为十进制。现在,数字类型的 toString()
方法也接受传出值的基数。所以如果我们把它放在一起看起来像这样。
(parseInt("F0", 16) + 1 ).toString(16) // returns f1
这取值 F0
,一个十六进制数字,将其转换为十进制加 1,然后 returns 返回一个十六进制字符串。
希望对您有所帮助!
编辑
为了更具体地回答您的问题,mac 地址的上下文是 00-FF,因此下面的内容将正确地用前导零填充,并使用模数 'wrap' 任何超过 FF 的数字回到 00 并再次向上。
("0"+ ((parseInt("FF", 16) + 1) % 256 ).toString(16)).substr(-2)
这是一个解决方案(不处理 FF
案例)
基本上是用parseInt
以16为基数转成数字,再用toString
以16为基数转为十六进制字符串
var _cnames = "84:8D:C7:BB:A3:F0";
var parts = _cnames.split(':');
var last = parts.pop();
var incremented = (parseInt(last,16) + 1).toString(16).toUpperCase().padStart(2,'0');
parts.push(incremented);
var updated = parts.join(':');
console.log(updated);
完整的解决方案
备注:
注意小于 8 的值
==> '04' +1 => '5'
,
并且需要添加 前导零 以获得正确的 MAC 地址
function nextMACaddress( MACaddress )
{
let hex = MACaddress.split(':').map(x=>parseInt(x,16))
plusOne(hex.length-1)
return hex.map(x=>('0'+x.toString(16).toUpperCase()).slice(-2)).join(':')
function plusOne(p) {
if (p<0) return
if (hex[p]==255) { hex[p]=0; plusOne(p-1) }
else { hex[p]++ }
}
}
console.log('84:1D:A2:B9:A3:D0 =>', nextMACaddress('84:1D:A2:B9:A3:D0') ) // 84:1D:A2:B9:A3:D1
console.log('84:1D:A2:B9:A3:99 =>', nextMACaddress('84:1D:A2:B9:A3:99') ) // 84:1D:A2:B9:A3:9A
console.log('84:1D:A2:B9:A3:AF =>', nextMACaddress('84:1D:A2:B9:A3:AF') ) // 84:1D:A2:B9:A3:B0
console.log('84:1D:A2:B9:A3:03 =>', nextMACaddress('84:1D:A2:B9:A3:03') ) // 84:1D:A2:B9:A3:04
console.log('84:1D:A2:FF:FF:FF =>', nextMACaddress('84:1D:A2:FF:FF:FF') ) // 84:1D:A3:00:00:00
console.log('FF:FF:FF:FF:FF:FF =>', nextMACaddress('FF:FF:FF:FF:FF:FF') ) // 00:00:00:00:00:00
您好,我对您的要求有点困惑:
- "For a given MAC address I need to change the last value to +1";所以你的意思是最后一个 "octet",最后一个冒号后面的最后两个字符?不是 非常 最后一个字符,也不是,至少在给出的几个答案中,比最后一个八位字节多?
- "84:1D:A2:B9:A3:99 => 需要更改为:84:1D:A2:B9:A3:A0" -- 我认为您在这里的十六进制数学可能不正确,将“99”结果加一在“9A”中不是 "A0"
- 最后,如果我对上面第一点的看法是正确的,我假设如果最后一个八位字节是“99”,你想回到“01”
(终于大声笑了,我可能错误地假设这些 macAddrs 在一个数组中,但它应该足够简单,可以从后面的 Array.map
方法中提取逻辑)
假设我对上面的内容是正确的,这里是我的简洁解决方案,它使用 ES2017 中的 padStart
,因此不受 IE 支持——注意我已经通过使用取消了拆分的需要(更简单?)切片, 受 IE
const macAddrs = [
'84:1D:A2:B9:A3:D0',
'84:1D:A2:B9:A3:99',
'84:1D:A2:B9:A3:AF',
'84:1D:A2:B9:A3:FF'
];
const addrsIncr = macAddrs.map(addr => {
let addrPrefix = addr.slice(0, 15); // everything up to and including last colon
let modulusIncrLastOctet = (parseInt(addr.slice(15), 16) + 1) % 256; // converts FF to 01
return addrPrefix + modulusIncrLastOctet.toString(16).padStart(2, 0).toUpperCase();
});
console.log(addrsIncr);
输出:
[ '84:1D:A2:B9:A3:D1',
'84:1D:A2:B9:A3:9A',
'84:1D:A2:B9:A3:B0',
'84:1D:A2:B9:A3:00' ]