我发布了一个函数,它将IPv6地址转换为128位无符号整数值:ColdFusion IPv6 to 128-bit unsigned int
我现在需要一个能够向另一个方向发展的功能。
这个功能变得更加复杂,我将解释答案的复杂性。
答案 0 :(得分:0)
以下是使用正确(简明)IPv6格式将128位无符号整数转换为IPv6地址的函数。
说明: 像这样的函数的部分问题是传递给函数(nUInt128)的数字不能保证是128位无符号整数。它可能是8位(:: 1)甚至是奇怪的东西,比如签名的136位数字(ColdFusion / Java似乎更喜欢签名的整数)。没有完全转换为具有16个值的Java Byte数组的128位数将导致java.net.Inet6Address.getAddress()抛出错误。我的解决方案是创建一个包含16个零的ColdFusion数组并对其进行反向填充,然后将其与java.net.Inet6Address.getAddress()一起使用。我很惊讶这是有效的,因为我不知道该数组中的数字有多大。 ColdFusion / Java以某种方式做了一些魔法并将数组转换为Byte []。反填充也剥离了更大的数字并修复了136位有符号整数问题。
<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()实用程序函数。
<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>
如果您有任何建议/问题,请发表评论。