ColdFusion 128位无符号int到IPv6 [英] ColdFusion 128-bit unsigned int to IPv6

查看:104
本文介绍了ColdFusion 128位无符号int到IPv6的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在此处发布了将IPv6地址转换为128位无符号int值的函数: ColdFusion IPv6到128位无符号整数

I've posted a function that will convert an IPv6 address to a 128-bit unsigned int value here: ColdFusion IPv6 to 128-bit unsigned int

我需要一个现在可以朝另一个方向运行的函数。

I need a function that will go in the other direction now.

该功能变得更加复杂,我将在答案中解释其复杂性。

This function turned out to be more complicated and I'll explain the complications in the answer.

推荐答案

此处是将128位无符号整数转换为具有正确(简洁)IPv6格式的IPv6地址的函数。

Here is the function that will convert a 128-bit unsigned int to an IPv6 address with the correct (concise) IPv6 formatting.

说明:
这样的函数的部分问题是,不能保证传递给函数(nUInt128)的数字是128位无符号整数。它可能是8位(:: 1)甚至是奇怪的东西,例如带符号的136位数字(ColdFusion / Java似乎更喜欢带符号的整数)。没有确切的128位数字转换为具有16个值的Java Byte数组将导致java.net.Inet6Address.getAddress()引发错误。我的解决方案是用16个零创建一个ColdFusion数组,然后回填它,然后将其与java.net.Inet6Address.getAddress()一起使用。我不知道该数组中的数字有多少,使我感到惊讶。 ColdFusion / Java以某种方式做了一些魔术,并将数组变成了Byte []。回填还去除了较大的数字,并解决了136位带符号的int问题。

Explanations: Part of the problem with a function like this is that the number passed into the function (nUInt128) is not guaranteed to be a 128-bit unsigned int. It might be 8-bits (::1) or even weird stuff like a signed 136-bit number (ColdFusion/Java seems to prefer signed ints). Not having exactly a 128-bit number that gets converted to a Java Byte array with 16 values will cause java.net.Inet6Address.getAddress() to throw an error. My solution was to create a ColdFusion array with 16 zeros and back-fill it and then use that with java.net.Inet6Address.getAddress(). I was surprised that this worked as I have no idea how large the numbers are in that array. ColdFusion/Java somehow did some magic and turned the array into a Byte[]. The back-fill also strips off the numbers that are larger and fixes the 136-bit signed int problem.

<cffunction name="UInt128ToIPv6" returntype="string" output="no" access="public" hint="returns IPv6 address for uint128 number">
    <cfargument name="nUInt128" type="numeric" required="yes" hint="uint128 to convert to ipv6 address">

    <cfif arguments.nUInt128 EQ 0>
        <cfreturn "">
    </cfif>

    <cftry>
        <cfset local['javaMathBigInteger'] = CreateObject("java", "java.math.BigInteger").init(arguments.nUInt128)>
        <cfset local['JavaNetInet6Address'] = CreateObject("java", "java.net.Inet6Address")>
        <cfset local['arrBytes'] = local.javaMathBigInteger.toByteArray()>

        <!--- correct the array length if !=16 bytes --->
        <cfset local['arrFixedBytes'] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]>
        <cfif arrayLen(local.arrBytes) NEQ 16>
            <cfset local['nFixedIndex'] = 16>
            <cfset local['nBytesIndex'] = arrayLen(local.arrBytes)>

            <cfloop condition="local.nFixedIndex NEQ 0 && local.nBytesIndex NEQ 0">
                <cfset local.arrFixedBytes[local.nFixedIndex] = local.arrBytes[local.nBytesIndex]>
                <cfset local.nFixedIndex-->
                <cfset local.nBytesIndex-->
            </cfloop>
        </cfif>
        <!--- /correct the array length if !=16 bytes --->

        <cfif arrayLen(local.arrBytes) NEQ 16>
            <cfset local['vcIPv6'] = local.JavaNetInet6Address.getByAddress(local.arrFixedBytes).getHostAddress()>
        <cfelse>
            <cfset local['vcIPv6'] = local.JavaNetInet6Address.getByAddress(local.javaMathBigInteger.toByteArray()).getHostAddress()>
        </cfif>
        <cfcatch type="any">
            <cfset local['vcIPv6'] = "">
        </cfcatch>
    </cftry>

    <cfreturn formatIPv6(vcIPv6 = local.vcIPv6)>
</cffunction>

以下是在上一个函数结尾处调用的formatIPv6()实用函数。

Here is the formatIPv6() utility function that is called at the end of the previous function.

<cffunction name="formatIPv6" returntype="string" output="yes" access="public" hint="returns a compressed ipv6 address">
    <cfargument name="vcIPv6" type="string" required="yes" hint="IPv6 address">

    <!--- inside reReplace removes leading zeros, outside reReplace removes repeating ":" and "0:" --->
    <cfreturn reReplace(reReplace(LCase(arguments.vcIPv6), "(:|^)(0{0,3})([1-9a-f]*)", "\1\3", "all"), "(^|:)[0|:]+:", "::", "all")>
</cffunction>

如果您有任何建议/问题,请发表评论。

If you have any suggestions/questions, please leave comments.

这篇关于ColdFusion 128位无符号int到IPv6的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆