Valhalla Legends Forums Archive | Battle.net Bot Development | [Python] Decode Cdkey

AuthorMessageTime
Yegg
I finally finished my decode starcraft cdkey function in Python. However, I want to know if it is returning the correct data, here is the function and below it is what it returns (if the key equals '1234567890123'):
[code]def starkey(self, key):
    arrayKey = list(key)
    is_valid = [False]
    v = 3
    for i in range(12):
        c = arrayKey[i]
        n = int(c)
        n2 = v * 2
        n = n ^ n2
        v = v + n
    v = v % 10
    if hex(v) == arrayKey[12]:
        is_valid[0] = True
    v = 194
    for i in range(11, 0, -1):
        if v < 7:
            v2 = 0x13AC9741
            for i in range(11, 0, -1):
                c = arrayKey[i]
                if ord(c) <= ord('7'):
                    v = v2
                    c2 = v and 0xFF
                    c2 = c2 and 7
                    c2 = c2 ^ c
                    v = int(v) >> 3
                    arrayKey[i] = c2
                    v2 = v
                elif ord(c) < 65:
                    c2 = int(i)
                    c2 = c2 and 1
                    c2 = c2 ^ c
                    arrayKey[i] = c2
        c = arrayKey[i]
        n = int(v/12)
        n2 = v % 12
        v = v - 17
        c2 = arrayKey[n2]
        arrayKey[i] = c2
        arrayKey[n2] = c
        decode_starcraft_key = ''.join(arrayKey)
        return decode_starcraft_key[/code]
It returns (if the key equals '1234567890123'):
[code]1224567890133
1224567891033
1224167895033
1224167835093
1224168735093
1824162735093
1824132765093
1821432765093
1820432765193
1830422765193
8130422765193[/code]
Can anyone tell me if it is returning the correct data or if something is wrong with my function?
April 17, 2005, 2:43 PM
laurion
I got 5263531935083 when I tried it using my function.
[code]
Public Function DecodeStarcraftKey(ByVal sKey As String)

    Dim r As Double, n As Double, n2 As Double, v As Double, _
    v2 As Double, keyvalue As Double, c1 As Byte, c2 As Byte, c As Byte, _
    bValid As Boolean, i As Integer, aryKey(0 To 12) As String
   
    For i = 1 To 13
   
        aryKey(i - 1) = Mid$(sKey, i, 1)
       
    Next i
   
    v = 3
   
    For i = 0 To 11
   
        c = aryKey(i)
        n = Val(c)
        n2 = v * 2
        n = n Xor n2
        v = v + n
       
    Next i
   
    v = v Mod 10
   
    If hex(v) = aryKey(12) Then
   
        bValid = True
       
    End If
   
    v = 194
   
    For i = 11 To 0 Step -1
   
        If v < 7 Then GoTo continue
        c = aryKey(i)
        n = CInt(v / 12)
        n2 = v Mod 12
        v = v - 17
        c2 = aryKey(n2)
        aryKey(i) = c2
        aryKey(n2) = c
       
    Next i
   
continue:

    v2 = &H13AC9741
   
    For i = 11 To 0 Step -1
   
        c = UCase$(aryKey(i))
        aryKey(i) = c
       
        If Asc(c) <= Asc("7") Then
       
            v = v2
            c2 = v And &HFF
            c2 = c2 And 7
            c2 = c2 Xor c
            v = RShift(CLng(v), 3)
            aryKey(i) = c2
            v2 = v
           
        ElseIf Asc(c) < 65 Then
       
            c2 = CByte(i)
            c2 = c2 And 1
            c2 = c2 Xor c
            aryKey(i) = c2
           
        End If
       
    Next i
   
    DecodeStarcraftKey = Join(aryKey, "")
   
    Erase aryKey()
   
End Function
[/code]
April 17, 2005, 5:31 PM
Yegg
My code in Python is (I think) identical to that. I don't see how they both return different values.
April 17, 2005, 5:39 PM
St0rm.iD
If you're trying to use bitwise operations, you want:
& instead of and
| instead of or
^ instead of xor

If you want ^ to raise something to a power (not xor), use the pow(base, exponent) function.
April 17, 2005, 6:37 PM
Yegg
Ok, this is getting weird, I changed my code to:
[code]def starkey(key):
    arrayKey = list(key)
    is_valid = [False]
    v = 3
    for i in range(12):
        c = arrayKey[i]
        n = int(c)
        n2 = v * 2
        n ^= n2
        v += n
    v = v % 10
    if hex(v) == arrayKey[12]:
        is_valid[0] = True
    v = 194
    for i in range(11, 0, -1):
        if v > 7:
            v2 = 0x13AC9741
            for i in range(11, 0, -1):
                c = arrayKey[i]
                if ord(c) <= ord('7'):
                    v = v2
                    c2 = v & 0xFF
                    c2 &= 7
                    c2 ^= int(c)
                    v = int(v) >> 3
                    arrayKey[i] = c2
                    v2 = v
                elif ord(c) < 65:
                    c2 = int(i)
                    c2 &= 1
                    c2 ^= int(c)
                    arrayKey[i] = c2
        c = arrayKey[i]
        n = int(v/12)
        n2 = v % 12
        v -= 17
        c2 = arrayKey[n2]
        arrayKey[i] = c2
        arrayKey[n2] = c
        decode_starcraft_key = ''.join(str(arrayKey))
        return decode_starcraft_key[/code]
Pretty much everything is the same, but where I have
[code]if v > 7:[/code]
It used to be:
[code]if v < 7:[/code]
I switched the sign. Instead of receiving '1224567890133', I now receive:
[code]"[3, '3', 2, 6, 0, 1, 1, 1, 1, 0, 2, 8, '6']"[/code]
I can't for the life of me figure out what is wrong with my code. I tried getting my function to receive 5263531935083 like laurion's did. But it just wont seem to do that. Any ideas?[code][/code]
April 17, 2005, 7:12 PM
Yoni
Change
[code]
        decode_starcraft_key = ''.join(str(arrayKey))
[/code]
to
[code]
        decode_starcraft_key = ''.join(map(str, arrayKey))
[/code]
April 17, 2005, 9:55 PM
St0rm.iD
Yoni codes python?
April 17, 2005, 10:47 PM
laurion
[quote author=Banana fanna fo fanna link=topic=11303.msg108926#msg108926 date=1113778062]
Yoni codes python?
[/quote]
who doesnt these days  ;D
April 17, 2005, 11:18 PM
Yegg
:D, why thank you Yoni. Here is my new function, only I am not receiving what laurion received, could his code be wrong?
[code]def starkey(key):
    arrayKey = list(key)
    is_valid = [False]
    v = 3
    for i in range(12):
        c = arrayKey[i]
        n = int(c)
        n2 = v * 2
        n ^= n2
        v += n
    v = v % 10
    if hex(v) == arrayKey[12]:
        is_valid[0] = True
    v = 194
    for i in range(11, 0, -1):
        if v > 7:
            v2 = 0x13AC9741
            for i in range(11, 0, -1):
                c = arrayKey[i]
                if ord(c) <= ord('7'):
                    v = v2
                    c2 = v & 0xFF
                    c2 &= 7
                    c2 ^= int(c)
                    v = int(v) >> 3
                    arrayKey[i] = c2
                    v2 = v
                elif ord(c) < 65:
                    c2 = int(i)
                    c2 &= 1
                    c2 ^= int(c)
                    arrayKey[i] = c2
        c = arrayKey[i]
        n = int(v/12)
        n2 = v % 12
        v -= 17
        c2 = arrayKey[n2]
        arrayKey[i] = c2
        arrayKey[n2] = c
        decode_starcraft_key = ''.join(map(str, arrayKey))
        return decode_starcraft_key[/code]
I now receive '1617474995133'. Is this correct if the cdkey is '1234567890123'?
April 18, 2005, 12:44 AM
laurion
I assure you my code is not wrong. However, I know no python, so I can't help you, sorry.
April 18, 2005, 12:49 AM
St0rm.iD
Are you doing any division that might require decimal points? If so, wrap the numbers in float().
April 18, 2005, 3:04 AM
Yegg
I don't seem to be receiving any decimal points in any of my numbers. I re did my function and did the last lines like Yoni said, and I now receive
[code]'8130422765193'[/code]
I'm guessing this is wrong because laurion got something different. I'll try using float() any ways. Here is my function for now:
[code]def starkey(key):
    arrayKey = list(key)
    v = 3
    for i in range(0, 11):
        c = arrayKey[i]
        n = int(c)
        n2 = v * 2
        n ^= n2
        v += n
    v %= 10
    if(hex(v) == arrayKey[12]):
        valid = [True]
    v = 194
    for i in range(11, 0, -1):
        if(v < 7):
            v2 = 0x13AC9741
            for i in range(11, 0, -1):
                c = arrayKey[i].upper()
                arrayKey[i] = c
                if(ord(c) <= ord('7')):
                    v = v2
                    c2 = v & 0xFF
                    c2 &= 7
                    c2 ^= c
                    v = int(v) >> 3
                    arrayKey[i] = c2
                    v2 = v
                elif(ord(c) < 65):
                    c2 = int(i)
                    c2 &= 1
                    c2 ^= c
                    arrayKey[i] = c2
        c = arrayKey[i]
        n = int(v/12)
        n2 = v % 12
        v -= 17
        c2 = arrayKey[n2]
        arrayKey[i] = c2
        arrayKey[n2] = c
    decode_starcraft_key = ''.join(map(str, arrayKey))
    return decode_starcraft_key[/code]
April 18, 2005, 1:51 PM
St0rm.iD
I fixed your code. Let me explain what I did

[code]
def starkey(key):
    arrayKey = list(key)
    v = 3
    for i in range(0, 12):
        c = arrayKey[i]
        n = int(c)
        n2 = v * 2
        n ^= n2
        v += n
    v %= 10
    if(hex(v) == arrayKey[12]):
        valid = [True]
    v = 194
    for i in range(11, -1, -1):
        if(v < 7):
            break
        c = arrayKey[i]
        n = int(v/12)
        n2 = v % 12
        v -= 17
        c2 = arrayKey[n2]
        arrayKey[i] = c2
        arrayKey[n2] = c

    v2 = 0x13AC9741
    for i in range(11, -1, -1):
        c = arrayKey[i].upper()
        arrayKey[i] = c
        if(ord(c) <= ord('7')):
            v = v2
            c2 = v & 0xFF
            c2 &= 7
            c2 ^= int(c)
            v = int(v) >> 3
            arrayKey[i] = c2
            v2 = v
        elif(ord(c) < 65):
            c2 = int(i)
            c2 &= 1
            c2 ^= int(c)
            arrayKey[i] = c2
       
    decode_starcraft_key = ''.join(map(str, arrayKey))
    return decode_starcraft_key

# 5263531935083

print starkey("1234567890123")
[/code]

First, all of your loops were off-by-one. range(0, 11) counts from 0 to 10, not 11. You have to add or subtract one, based on your step value.

Second, your inner loop was messed up. Instead of having if v < 7 and then putting the code, I entered a break and put the code after the loop. This is because it had to execute whenever the loop exited, whether or not v < 7. Finally, you needed to coerce c to int in order for the xor to work at the bottom.

Examine the differences in the code and compare it to the VB code; it will help you learn.
April 18, 2005, 3:03 PM
Yegg
Thanks banana fanna fo fanna. I'll look over your code. I re did my function too, I just didn't think anything was off at all. Thanks again. Ok, I tried the code and it works just fine.
April 18, 2005, 3:09 PM
aton
your python looks like c...
[code]
def decodekey(cdkey):
    """ decodes a cdkey into public value, private value and product
        in: cdkey(string)
        out: product (int)
        out: public value (int)
        out: private value (int)
    """
   
    if len(cdkey)!=13:
        print "decodekey(): key needs length 13\n"
        return 0,0,0
   
    key=map(int, cdkey)
   
    # verification
    accum=3
    for n in range(0, 12):
        accum+=(key[n])^(accum*2)
       
    if (accum%10)!=key[12]:
        print "decodekey(): verification failed\n"
        return 0,0,0
   
    #shuffling
    pos=0x0b
    for n in range(0xc2, 6, -0x11):
        key[pos],key[n%0x0c] = key[n%0x0c], key[pos]
        pos-=1
   
    #final value
    hash=0x13AC9741
    for n in range(11, -1, -1):
        if key[n]<=7:
            key[n]^= (hash & 7)
            hash>>=3
        else:
            key[n]^= (n&1)
       
    #extraction
    values="".join(map(str, key))
    product=values[:2]
    public=values[2:9]   
    private=values[9:12]
   
    return product, public, private
[/code]
May 3, 2009, 1:14 PM
Yegg
I haven't touched this function in a very long time, but the latest implementation of it I have on my computer is the one below. It doesn't do the checksum to verify if the key is valid and it doesn't split the key into its 3 values in this, I did those tasks in separate functions.

[code]def decodeStarcraftKey(key):
    arrayKey = list(key)
    n = 11
    v = 0x13AC9741
    for i in (8, 10, 4, 5, 7, 1, 11, 3, 9, 2, 0, 6):
        c = int(key[i])
        if c < 7:
            c = v & 0xFF & 7 ^ c
            v >>= 3
        else:
            c = n & 1 ^ c
        arrayKey[n] = c
        n -= 1
    return ''.join(map(str, arrayKey))[/code]
May 3, 2009, 8:41 PM

Search