[英]IPv6 as a comparable JavaScript string?
在IPv4時代,事情很容易,因為IPv4地址可以轉換為簡單的32位整數,然后用於各種比較計算。
使用IPv6有點尷尬,因為一方面,JavaScript本身不支持128位整數,而且它們的轉換也不是那么簡單。 這只剩下處理IPv6字符串表示形式的選項。
如何將任何已知格式的IPv6地址轉換為可比較的字符串?
A < B
必須在JavaScript中產生true
。 類似的邏輯對於其余比較必須有效: ===
, <=
, >
和>=
。 將簡化的IPv6地址格式轉換為完整格式並不是很困難。 只有3條規則可以簡化地址。 以下是按順序排列的規則,必須將它們撤消才能將地址轉換回完整格式:
點分四進制表示法(IPv4地址嵌入在IPv6地址內)
前導零可以省略
零組可以縮寫為::
從技術上講,根據您的處理方式,可能會交換2和3。
因此,這是一個僅轉換有效IPv6地址的簡單轉換器(如果您向它提供無效的IPv6地址,因為我沒有進行任何驗證,這肯定會失敗,這很麻煩):
function full_IPv6 (ip_string) {
// replace ipv4 address if any
var ipv4 = ip_string.match(/(.*:)([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$)/);
if (ipv4) {
var ip_string = ipv4[1];
ipv4 = ipv4[2].match(/[0-9]+/g);
for (var i = 0;i < 4;i ++) {
var byte = parseInt(ipv4[i],10);
ipv4[i] = ("0" + byte.toString(16)).substr(-2);
}
ip_string += ipv4[0] + ipv4[1] + ':' + ipv4[2] + ipv4[3];
}
// take care of leading and trailing ::
ip_string = ip_string.replace(/^:|:$/g, '');
var ipv6 = ip_string.split(':');
for (var i = 0; i < ipv6.length; i ++) {
var hex = ipv6[i];
if (hex != "") {
// normalize leading zeros
ipv6[i] = ("0000" + hex).substr(-4);
}
else {
// normalize grouped zeros ::
hex = [];
for (var j = ipv6.length; j <= 8; j ++) {
hex.push('0000');
}
ipv6[i] = hex.join(':');
}
}
return ipv6.join(':');
}
您可能可以在.split(':')
之后進行嵌入式IPv4處理,但我已經在編寫時考慮了regexp。 從上面的代碼可以看出,該過程的每個步驟都非常簡單。 使我感到震驚的唯一原因是在最后一個for循環中j<=8
情況下出現了一次錯誤的錯誤。
您沒有指出解決方案是否可接受第三方庫,但如果可以,我相信您可以使用ip-address庫及其依賴項jsbn將每個地址解析為v6對象,調用v6.bigInteger()
以jsbn BigInteger對象的形式獲取地址,然后使用BigInteger.compareTo
比較地址。
只需將IPv6地址轉換為四個32位無符號整數,然后在這四個整數上循環即可。 我一直這樣做:
操作IPv4或IPv6地址只需要兩件事:地址和掩碼。 每種協議的長度都相同(IPv4 = 32位,IPv6 = 128位)。 由於我沒有128位無符號整數,因此我對IPv6地址和掩碼使用了四個32位無符號整數的數組。 其他所有內容都可以從這兩個值構建。
IPv6比IPv4更容易找到第一個和最后一個地址,因為在IPv6中,第一個地址是子網,而最后一個地址是子網加反掩碼。
使用ip6
npm軟件包對IPv6地址進行規范化,然后直接進行比較。
let ip6 = require('ip6')
console.log(ip6.normalize('2404:6800:4003:808::200e'));
// 2404:6800:4003:0808:0000:0000:0000:200e
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.