Punycode IDN Konverter

  • Hallo,

    ich bin auf der Suche nach einem Punycode IDN Konverter für Domainnamen.
    Auf der Seite http://www.simpledns.com/addons.aspx gibt es z.B. eine Net 2.0 DLL die das kann.
    Falls es möglich ist diese DLL-Datei in Autoit einzubinden, oder es andere Möglichkeiten gibt
    schreib mir doch bitte was es mich kosten würde wenn du mir ein Script in Autoit erstellst.

    Danke.

    ciao
    Cybercommander

  • Eine GUI brauche ich gar nicht, ich habe eine Liste mit domainnamen die konvertiert werden sollen.
    Eigentlich brauche ich nur eine UDF oder Funktion die mir den übergebenen domainnamen konvertiert und als idn oder punycode zurück gibt, je nachdem was ich gewählt habe.
    Kannst du mir sowas programmieren ?

    • Offizieller Beitrag

    ohne dll. mit der Berechnung aus der ASP Version, umgeschrieben in AutoIt. die Credits gehen demnach für die Denkarbeit an http://www.simpledns.com !
    Gar nicht sooo schwer, wenn man etwas Zeit dafür hat. Ich hab 3 Anläufe gebraucht. Besonders die ganzen Loop Schleifen umzubauen.

    Spoiler anzeigen
    [autoit]

    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_UseUpx=n
    #AutoIt3Wrapper_Change2CUI=y
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

    [/autoit] [autoit][/autoit] [autoit]

    if $CmdLine[2] = 0 Then
    ConsoleWrite(DomainPunyEncode($CmdLine[1]))
    Else
    ConsoleWrite(DomainPunyDecode($CmdLine[1]))
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Func IIf($a,$b,$c)
    If $a Then
    return $b
    Else
    return $c
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func idiv ($a, $b)
    $result = $a / $b
    If StringInStr($result, ".") > 0 Then
    $result = StringSplit($result, ".")
    $erg = $result[1]
    Else
    $erg = $result
    EndIf
    return $erg
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func printhelp($text)
    ConsoleWrite($text)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func StringInStrRev($text, $delim)
    $return = StringInStr($text, $delim, 0, -1)
    Return $return
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func DomainPunyEncode($domStr)
    Dim $i, $segStr, $segPuny, $x, $outStr
    $domStr = StringLower($domStr)
    $outStr = ""
    While stringLen($domStr) > 0
    $i = stringInstr($domStr,".")-1
    If $i < 0 Then $i = stringlen($domStr)
    If $i = 0 Then printhelp("Invalid placement of dot in domain name")
    If $i > 63 Then printhelp("Invalid domain name - segment between dots longer than 63 characters")
    $segStr = stringleft($domStr, $i)
    $domStr = stringMid($domStr, $i + 2)
    $segPuny = False
    ;REM check valid chars
    For $i = 1 To stringlen($segStr)
    If AscW(stringmid($segStr, $i, 1)) > 127 Then
    $segPuny = True
    Else
    If stringInstr("abcdefghijklmnopqrstuvwxyz0123456789-",stringmid($segStr,$i,1)) = 0 Then printhelp("Invalid character in domain name")
    EndIf
    Next
    If $segPuny Then
    $x = "xn--" & PunyEncode($segStr)
    Else
    $x = $segStr
    EndIf
    If stringlen($x) > 63 Then
    printhelp("Invalid domain name - encoded segment longer than 63 characters")
    EndIf
    $outStr = $outStr & IIf(stringlen($outStr) > 0, ".", "") & $x
    Wend
    return $outStr
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func DomainPunyDecode($domStr)
    Dim $i, $segStr, $outStr
    $domStr = StringLower($domStr)
    $outStr = ""
    While stringlen($domStr) > 0
    $i = stringinstr($domStr,".")-1
    If $i < 0 Then $i = stringlen($domStr)
    If $i = 0 Then printhelp("Invalid placement of dot in domain name")
    If $i > 63 Then printhelp("Invalid domain name - segment between dots longer than 63 characters")
    $segStr = stringleft($domStr,$i)
    $domStr = stringMid($domStr, $i + 2)
    ;REM check valid chars
    For $i = 1 To stringlen($segStr)
    If stringinstr("abcdefghijklmnopqrstuvwxyz0123456789-",stringmid($segstr,$i,1))=0 Then printhelp("Invalid character in domain name")
    Next
    If stringLeft($segStr, 4) = "xn--" Then
    $outStr = $outStr & IIf(stringlen($outStr) > 0, ".", "") & PunyDecode(stringmid($segStr,5))
    Else
    $outStr = $outStr & IIf(stringlen($outStr) > 0, ".", "") & $segStr
    EndIf
    Wend
    return $outStr
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func PunyDecode($pc)
    Dim $outBufPos, $i, $digit, $outStr, $bias, $n, $t, $pcPos, $oldi, $w, $k
    $outBufPos = 0
    $outStr = ""

    [/autoit] [autoit][/autoit] [autoit]

    ;REM handle basic code points (clear text)
    $i = stringinStrRev($pc, "-") - 1
    If $i >= 0 Then
    $outBufPos = $i
    $outStr = stringLeft($pc,$i)
    $pc = stringmid($pc,$i + 2)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;REM main decoding loop
    $i = 0
    $bias = 72
    $n = 128
    $pcPos = 0

    [/autoit] [autoit][/autoit] [autoit]

    While $pcPos < stringlen($pc)
    $oldi = $i
    $w = 1
    $k = 36
    While $digit >= $t
    If $pcPos >= stringlen($pc) Then printhelp("Not a valid punycode domain. Bad input.")
    $digit = PunyDecodeDigit(AscW(stringMid($pc, $pcPos + 1, 1)))
    $pcPos = $pcPos + 1
    $i = $i + $digit * $w
    $t = IIf($k <= $bias, 1, IIf($k >= $bias + 26, 26, $k - $bias))
    $w = $w * (36 - $t)
    $k = $k + 36
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    $bias = PunyAdapt($i - $oldi, $outBufPos + 1, ($oldi = 0))
    $n = $n + idiv($i,($outBufPos + 1))
    $i = Mod($i,($outBufPos + 1))

    [/autoit] [autoit][/autoit] [autoit]

    ;REM insert n at position i of the output
    $outStr = stringleft($outStr, $i) & ChrW($n) & stringmid($outStr, $i+1)
    $i = $i + 1

    [/autoit] [autoit][/autoit] [autoit]

    ;REM prepare next loop
    $outBufPos = $outBufPos + 1
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    return $outStr
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func PunyDecodeDigit($ascVal)
    If $ascVal >= 65 And $ascVal <= 90 Then
    $return = $ascVal - 65
    return $return
    ElseIf $ascVal >= 97 And $ascVal <= 122 Then
    $return = $ascVal - 97
    return $return
    ElseIf $ascVal >= 48 And $ascVal <= 57 Then
    $return = $ascVal - 22
    return $return
    Else
    printhelp("Not a valid punycode domain. Bad input.")
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func PunyEncodeDigit($dgVal)
    If $dgVal < 26 Then
    $return = Chr(97 + $dgVal)
    return $return
    ElseIf $dgVal < 36 Then
    $return = Chr(22 + $dgVal)
    return $return
    Else
    printhelp("Bad value for punycode digit encoding")
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func PunyAdapt($delta, $numpoints, $firsttime)
    dim $k
    $delta = IIf($firsttime, idiv($delta, 700), idiv($delta, 2))
    $delta = $delta + idiv($delta, $numpoints)
    $k = 0
    While $delta > 455
    $delta = idiv($delta, 35)
    $k = $k + 36
    Wend
    $return = $k + 36 * idiv($delta,($delta + 38))
    return $return
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func PunyEncode($uc)
    Dim $j, $t, $outStr, $n, $delta, $bias, $h, $b, $m, $q, $k
    $outStr = ""
    $n = 128
    $delta = 0
    $bias = 72

    [/autoit] [autoit][/autoit] [autoit]

    ;REM handle the basic code points
    For $j = 1 To stringlen($uc)
    If AscW(stringmid($uc, $j, 1)) < 128 Then $outStr = $outStr & StringLower(stringmid($uc, $j, 1))
    Next

    [/autoit] [autoit][/autoit] [autoit]

    $h = stringLen($outStr)
    $b = $h
    If $b > 0 Then
    $outStr = $outStr & "-"
    Endif

    [/autoit] [autoit][/autoit] [autoit]

    ;REM main encoding loop
    While $h < stringlen($uc)
    $m = -1
    For $j = 1 To stringlen($uc)
    If AscW(stringmid($uc, $j, 1)) >= $n And ($m = -1 Or AscW(stringmid($uc, $j, 1)) < $m) Then $m = AscW(stringmid($uc, $j, 1))
    Next
    $delta = $delta + ($m - $n) * ($h + 1)
    $n = $m

    [/autoit] [autoit][/autoit] [autoit]

    For $j = 1 To stringlen($uc)
    If AscW(stringmid($uc, $j, 1)) < $n Then $delta = $delta + 1
    If AscW(stringmid($uc, $j, 1)) = $n Then
    $q = $delta
    $k = 36
    while $q >= $t
    $t = IIf($k <= $bias, 1, IIf($k >= $bias + 26, 26, $k - $bias))
    $outStr = $outStr & PunyEncodeDigit($t + Mod(($q - $t),(36 - $t)))
    $q = idiv(($q - $t),(36 - $t))
    $k = $k + 36
    Wend
    $outStr = $outStr & PunyEncodeDigit($q)
    $bias = PunyAdapt($delta, $h + 1, $h = $b)
    $delta = 0
    $h = $h + 1
    EndIf
    Next
    $delta = $delta + 1
    $n = $n + 1
    Wend

    [/autoit] [autoit][/autoit] [autoit]

    return $outStr
    EndFunc

    [/autoit]

    Anbei die Exe.

    Aufruf mittels:

    Code
    puny.exe domäne.de 0

    encodiert

    Code
    puny.exe xn--domne-ira.de 1

    decodiert.


    Links ist der Spenden-Knopf. Wäre schlön, wenn da wirklich was rüber kommt ;)

    Grüße

    Gun-Food