簡體   English   中英

Classic ASP 中 ipv6 地址的字符串表示

[英]String representation of an ipv6 address in Classic ASP

出於地理定位的目的,我試圖獲取 ip v6 地址的數值的字符串表示形式。 因為 Classic ASP 不處理 bigint 值,所以我嘗試使用 Javascript function 來解決它。

基於這個使用biginteger.js庫的工作小提琴: https://jsfiddle.net/adamish/mrx3880p/ ,我調整了該庫以作為 ASP 的有效包含。

var ip = '2a00:85c0:0001:0000:0000:0000:0241:0023';


// simulate your address.binaryZeroPad(); method
var parts = [];
ip.split(":").forEach(function(it) {
    var bin = parseInt(it, 16).toString(2);
    while (bin.length < 16) {
        bin = "0" + bin;
    }
    parts.push(bin);
})
var bin = parts.join("");

// Use BigInteger library
var dec = bigInt(bin, 2).toString();
console.log(dec);

Fiddle 中的代碼將 ipv6 轉換為其二進制表示,然后調用 toString function,請求以基數 2 進行轉換。

它在小提琴中工作。 但是,我無法讓它在我的代碼中工作,因為返回值是科學計數法,這對我不利。

目標是輸入字符串“2a00:85c0:1::241:23”(或其非縮短版本,“2a00:85c0:0001:0000:0000:0000:0241:0023”,沒關系)和output 數字等價物的字符串表示形式,或“55830288595252163998698714105846497315”。

由於我僅限於可以在 Classic ASP 中使用的內容,有沒有人知道如何讓這種轉換工作?

不幸的是,您將無法執行此操作,因為 VBScript 和 JScript 無法處理所需的數值精度。

這是我在 VBScript 中的第一次嘗試

<%
Option Explicit
Const base = 65536
Dim ipv6: ipv6 = "2a00:85c0:0001:0000:0000:0000:0241:0023"
Dim pwr: pwr = 8
Dim hextets: hextets = Split(ipv6, ":")
Dim hextet, ipnum
If IsArray(hextets) Then
  For Each hextet In hextets
    pwr = pwr - 1
    ipnum = ipnum + ((base^pwr) * CLng("&h" & hextet))
  Next
End If
%>
<!doctype html>
<html>
  <head>
    <title>IPv6 to IP Number</title>
  </head>

  <body>
    <pre><%= ipv6 %></pre>
    <pre><%= FormatNumber(ipnum, 0, -2, -2, false) %></pre>
  </body>
</html>

Output:

2a00:85c0:0001:0000:0000:0000:0241:0023
55830288595252200000000000000000000000

這里的問題是計算是正確的,但是數字不能處理精度,所以當它達到最大值時,它默認為0

我的下一個嘗試是 JScript(不是我最強的語言)

<% @Language = "JScript" %>
<%
var base = 65536;
var ipv6 = "2a00:85c0:0001:0000:0000:0000:0241:0023";
var pwr = 8;
var hextets = ipv6.split(":");
var ipnum;

for (var hextet in hextets) {
  pwr--;
  ipnum += (Math.pow(base, pwr) * parseInt("0x" + hextets[hextet]));
};
%>
<!doctype html>
<html>
  <head>
    <title>IPv6 to IP Number</title>
  </head>

  <body>
    <pre><%= ipv6 %></pre>
    <pre><%= ipnum %></pre>
  </body>
</html>

Output:

2a00:85c0:0001:0000:0000:0000:0241:0023
-1.#IND

這次它失敗並出現-1.#IND轉換錯誤,這基本上意味着數字太大而無法表示。

So while not doable directly in VBScript or JScript you could still build a COM exposed class in another language (C#, VB.Net etc) that did the computation and produced a string that VBScript / Jscript could display.


有用的鏈接

我刪除了我之前的答案,因為它不是很有幫助。 已經確定您不能使用經典 ASP 將 IPv6 地址轉換為使用 VBscript 的數值。 JScript 可能是可能的,但似乎不太可能。

我還在高流量經典 ASP 網站上轉換和記錄 IPv4/6 數值以用於地理定位。

對於 IPv4,使用 VBscript 進行轉換非常簡單:

Function IPv4ToNumber(ByVal IPv4)

    Dim i, Pos, PrevPos, Num

    For i = 1 To 4

        Pos = InStr(PrevPos + 1, IPv4, ".", 1)
        If i = 4 Then pos = Len(IPv4) + 1
        Num = Int(Mid(IPv4, PrevPos + 1, Pos - PrevPos - 1))
        PrevPos = Pos
        IPv4ToNumber = ((Num Mod 256) * (256 ^ (4 - i))) + IPv4ToNumber

    Next

End function

這是另一個有用的 VBscript function,它返回 IP 的類型(IPv4、IPv6 或無效 IP 的空字符串)。 你可以只使用InStr()

. = IPv4

: = IPv6

但是這個 function 使用正則表達式來正確驗證 IP 地址:

Function IP_Type(ByVal IP)

    IP_Type = "" ' Default
    
    ' Check for valid IPv4 and IPv6 addresses
    
    Dim IP_RegExp
    
    If Len(IP) >= 7 AND Len(IP) <= 15 Then
    
        ' Potential IPv4
        
        Set IP_RegExp = New RegExp
        
            IP_RegExp.Pattern = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
            IP_Type = IP_RegExp.Test(IP)
            
            If IP_Type Then IP_Type = "IPv4" Else IP_Type  = ""
        
        Set IP_RegExp = Nothing
    
    ElseIf Len(IP) > 15 AND Len(IP) <= 39 Then
    
        ' Potential IPv6
        
        Set IP_RegExp = New RegExp
        
            IP_RegExp.Pattern = "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$"
            IP_Type = IP_RegExp.Test(IP)
            
            If IP_Type Then IP_Type = "IPv6" Else IP_Type  = ""
        
        Set IP_RegExp = Nothing
    
    End If
    
End Function

對於 IPv6,我使用 MySQL 來計算數值。 這是一個簡單的 SELECT 示例:

SELECT CAST(
    CONV(
        SUBSTR(
            HEX(
                INET6_ATON('2a00:85c0:0001:0000:0000:0000:0241:0023')
            )
        ,1,16)
    ,16,10
)AS DECIMAL(65))
*18446744073709551616
+CAST(
    CONV(
        SUBSTR(
            HEX(
                INET6_ATON('2a00:85c0:0001:0000:0000:0000:0241:0023')
            )
        ,17,16)
    ,16,10
) AS DECIMAL(65)) AS ipv6_num;

Output: 55830288595252163998698714105846497315 (使用完整或縮短的 IPv6 地址)

它也適用於 MariaDB。 對於其他 SQL 平台,邏輯相同,但語法和功能可能需要替換為等效的。

如果您為地理定位目的記錄 IP 數值,那么您顯然正在使用數據庫,因此為其他 SQL 平台調整上述 MySQL 代碼是我可以提供的最佳解決方案。

I also looked up an IP to numeric API (free or subscription based) but there doesn't seem to be any (IPv6 is still quite rare, so a REST API call could be a possible solution). Hopefully there is a solution using JScript, or as already mentioned you could use a COM DLL (I have experience with this, I've created a number of COM DLL's using C# for use in Classic ASP applications on my GitHub page . You will need雖然是 root 訪問權限。我正在使用一台新的筆記本電腦,因此需要重新安裝 Visual Studio,但是當我得到時間時,我將為 IP 創建一個 COM DLL 到數值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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