• Welcome to Valhalla Legends Archive.
 

[Python] Decode Cdkey

Started by Yegg, April 17, 2005, 09:43 AM

Previous topic - Next topic

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'):
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

It returns (if the key equals '1234567890123'):
1224567890133
1224567891033
1224167895033
1224167835093
1224168735093
1824162735093
1824132765093
1821432765093
1820432765193
1830422765193
8130422765193

Can anyone tell me if it is returning the correct data or if something is wrong with my function?

Tazo

I got 5263531935083 when I tried it using my function.

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

Yegg

My code in Python is (I think) identical to that. I don't see how they both return different values.

Banana fanna fo fanna

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.

Yegg

#4
Ok, this is getting weird, I changed my code to:
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

Pretty much everything is the same, but where I have
if v > 7:
It used to be:
if v < 7:
I switched the sign. Instead of receiving '1224567890133', I now receive:
"[3, '3', 2, 6, 0, 1, 1, 1, 1, 0, 2, 8, '6']"
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?

Yoni

Change

        decode_starcraft_key = ''.join(str(arrayKey))

to

        decode_starcraft_key = ''.join(map(str, arrayKey))

Banana fanna fo fanna


Tazo


Yegg

:D, why thank you Yoni. Here is my new function, only I am not receiving what laurion received, could his code be wrong?
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

I now receive '1617474995133'. Is this correct if the cdkey is '1234567890123'?

Tazo

I assure you my code is not wrong. However, I know no python, so I can't help you, sorry.

Banana fanna fo fanna

Are you doing any division that might require decimal points? If so, wrap the numbers in float().

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
'8130422765193'
I'm guessing this is wrong because laurion got something different. I'll try using float() any ways. Here is my function for now:
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

Banana fanna fo fanna

I fixed your code. Let me explain what I did


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")


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.

Yegg

#13
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.

aton

#14
your python looks like c...

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