简体   繁体   English

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

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

For geolocation purposes, I am trying to get a string representation of the numeric value of an ip v6 address.出于地理定位的目的,我试图获取 ip v6 地址的数值的字符串表示形式。 Because Classic ASP doesn't handle bigint values, I'm attempting to work around it with a Javascript function.因为 Classic ASP 不处理 bigint 值,所以我尝试使用 Javascript function 来解决它。

Based on this working Fiddle: https://jsfiddle.net/adamish/mrx3880p/ that uses the biginteger.js library, I adapted the library to work as a valid include for ASP.基于这个使用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);

The code in the Fiddle converts the ipv6 into its binary representation then calls the toString function, requesting the conversion in base 2. Fiddle 中的代码将 ipv6 转换为其二进制表示,然后调用 toString function,请求以基数 2 进行转换。

It works in the Fiddle.它在小提琴中工作。 However, I can't get it to work in my code as the return value is in scientific notation, which is not good for me.但是,我无法让它在我的代码中工作,因为返回值是科学计数法,这对我不利。

The goal is to input the string "2a00:85c0:1::241:23" (or its non shortened version, "2a00:85c0:0001:0000:0000:0000:0241:0023", doesn't matter) and output a string representation of the numeric equivalent, or "55830288595252163998698714105846497315".目标是输入字符串“2a00:85c0:1::241:23”(或其非缩短版本,“2a00:85c0:0001:0000:0000:0000:0241:0023”,没关系)和output 数字等价物的字符串表示形式,或“55830288595252163998698714105846497315”。

As I am limited to what I can use in Classic ASP, has anyone any pointer on how I can get that conversion to work?由于我仅限于可以在 Classic ASP 中使用的内容,有没有人知道如何让这种转换工作?

Unfortunately, you won't be able to do this because VBScript and JScript can't handle the numerical precision required.不幸的是,您将无法执行此操作,因为 VBScript 和 JScript 无法处理所需的数值精度。

Here was my first attempt in VBScript这是我在 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: Output:

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

The problem here is the calculation is right but the number can't handle the precision so when it reaches the maximum it defaults to 0 .这里的问题是计算是正确的,但是数字不能处理精度,所以当它达到最大值时,它默认为0

My next attempt was JScript (not my strongest language)我的下一个尝试是 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: Output:

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

This time it fails with a -1.#IND conversion error which basically means the number is too big to be represented.这次它失败并出现-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. 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.


Useful Links有用的链接

I deleted my previous answer as it wasn't very helpful.我删除了我之前的答案,因为它不是很有帮助。 Its been established that you can't use Classic ASP to convert an IPv6 address to a numeric value using VBscript.已经确定您不能使用经典 ASP 将 IPv6 地址转换为使用 VBscript 的数值。 JScript could be possible, but seems unlikley. JScript 可能是可能的,但似乎不太可能。

I also convert and log IPv4/6 numeric values for geolocation purposes on a high traffic Classic ASP website.我还在高流量经典 ASP 网站上转换和记录 IPv4/6 数值以用于地理定位。

For IPv4, the conversion is quite simple using VBscript:对于 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

Here's another useful VBscript function that returns the type of IP (IPv4, IPv6 or an empty string for invalid IPs).这是另一个有用的 VBscript function,它返回 IP 的类型(IPv4、IPv6 或无效 IP 的空字符串)。 You could just use InStr() :你可以只使用InStr()

. = IPv4 = IPv4

: = IPv6 : = IPv6

But this function uses regular expressions to properly validate IP addresses:但是这个 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

For IPv6, I use MySQL to calculate the numeric value.对于 IPv6,我使用 MySQL 来计算数值。 Here's a simple SELECT example:这是一个简单的 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 (using either the full or shortened IPv6 address) Output: 55830288595252163998698714105846497315 (使用完整或缩短的 IPv6 地址)

It also works with MariaDB.它也适用于 MariaDB。 For other SQL platforms, the logic is the same, but the syntax and functions will probably need to be replaced with equivalents.对于其他 SQL 平台,逻辑相同,但语法和功能可能需要替换为等效的。

If you're logging IP numeric values for geolocation purposes, you're obviously using a database, so adapting the above MySQL code for other SQL platforms is the best solution I can offer.如果您为地理定位目的记录 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). 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 access though. I'm using a new laptop so will need to reinstall Visual Studio, but I'll create a COM DLL for IP to numeric values when I get the time). 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