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?
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
My code in Python is (I think) identical to that. I don't see how they both return different values.
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.
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?
Change
decode_starcraft_key = ''.join(str(arrayKey))
to
decode_starcraft_key = ''.join(map(str, arrayKey))
Yoni codes python?
: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'?
I assure you my code is not wrong. However, I know no python, so I can't help you, sorry.
Are you doing any division that might require decimal points? If so, wrap the numbers in float().
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
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.
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.
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
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.
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))