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

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

问题描述

我在这里发布了一个将 IPv6 地址转换为 128 位无符号整数值的函数: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 位 unsigned int 转换为具有正确(简洁)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 字节数组将导致 java.net.Inet6Address.getAddress() 引发错误.我的解决方案是创建一个包含 16 个零的 ColdFusion 数组并回填它,然后将其与 java.net.Inet6Address.getAddress() 一起使用.我很惊讶这行得通,因为我不知道该数组中的数字有多大.ColdFusion/Java 不知何故做了一些魔术并将数组变成了 Byte[].回填还会去除较大的数字并修复 136 位有符号整数问题.

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]*)", "13", "all"), "(^|:)[0|:]+:", "::", "all")>
</cffunction>

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

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

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

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