[英]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.