128-битное целое без знака ColdFusion в IPv6

Я разместил здесь функцию, которая преобразует IPv6-адрес в 128-битное целочисленное значение без знака: ColdFusion IPv6 в 128-битное целое число без знака

Мне нужна функция, которая теперь пойдет в другом направлении.

Эта функция оказалась более сложной, и я объясню сложности в ответе.


person Scott Jibben    schedule 04.04.2017    source источник
comment
codereview.stackexchange.com может быть?   -  person Henry    schedule 04.04.2017
comment
По всей видимости. Кто-то просил посмотреть эти функции из другого вопроса. Подобные вещи (отрицательные оценки без каких-либо объяснений) ДЕЙСТВИТЕЛЬНО заставляют человека вообще не хотеть вносить свой вклад.   -  person Scott Jibben    schedule 05.04.2017


Ответы (1)


Вот функция, которая преобразует 128-битное целое число без знака в адрес IPv6 с правильным (кратким) форматированием IPv6.

Объяснения: Часть проблемы с такой функцией заключается в том, что число, переданное в функцию (nUInt128), не обязательно является 128-битным целым числом без знака. Это могут быть 8-битные (::1) или даже странные вещи, такие как 136-битное число со знаком (похоже, ColdFusion/Java предпочитает знаковые целые числа). Отсутствие точного 128-битного числа, которое преобразуется в массив байтов Java с 16 значениями, приведет к тому, что java.net.Inet6Address.getAddress() выдаст ошибку. Мое решение состояло в том, чтобы создать массив ColdFusion с 16 нулями и заполнить его, а затем использовать его с 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>

Если у вас есть какие-либо предложения/вопросы, пожалуйста, оставьте комментарии.

person Scott Jibben    schedule 04.04.2017
comment
ИМХО, это должно быть в <cfscript> - person James A Mohler; 05.04.2017