簡體   English   中英

將IPv6作為可比較的JavaScript字符串?

[英]IPv6 as a comparable JavaScript string?

前言

在IPv4時代,事情很容易,因為IPv4地址可以轉換為簡單的32位整數,然后用於各種比較計算。

使用IPv6有點尷尬,因為一方面,JavaScript本身不支持128位整數,而且它們的轉換也不是那么簡單。 這只剩下處理IPv6字符串表示形式的選項。

如何將任何已知格式的IPv6地址轉換為可比較的字符串?

要求

  1. 對於任何可比較的字符串,如果地址A在地址B之前,則條件A < B必須在JavaScript中產生true 類似的邏輯對於其余比較必須有效: ===<=>>=
  2. 對於每個IPv6,必須生成盡可能多的字符串以覆蓋地址中的每個范圍,即每個范圍的起始地址+結束地址。

將簡化的IPv6地址格式轉換為完整格式並不是很困難。 只有3條規則可以簡化地址。 以下是按順序排列的規則,必須將它們撤消才能將地址​​轉換回完整格式:

  1. 點分四進制表示法(IPv4地址嵌入在IPv6地址內)

  2. 前導零可以省略

  3. 零組可以縮寫為::

從技術上講,根據您的處理方式,可能會交換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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM