Author | Message | Time |
---|---|---|
Ringo | hmm, how do i say this.. i suck at math :-\ So, what i need to do is calculate 2 numbers through a formula from 2 seed numbers, but the problem is getting the 2 seed values back! The seed numbers can be anything from 0 to 23. Example: [code] Dim A&, B& Const Seed1& = &H1, Seed2& = &H2 A = Seed1 * &H3 A = Seed2 + (A * &H8) If A > &H100 Then A = A - &H100 'A now 26 (&H1A) B = ((RShift(A, &H4) And &HF) + &H30) 'B now 49 (&H31) A = ((A And &HF) + &H30) 'A now 58 (&H3A) If A > &H39 Then A = A + &H7 'A now 65 (&H41) If B > &H39 Then B = B + &H7 'B remain 49 (&H31) [/code] Now, how to get 1 and 2 back? (The value of the seeds) [code] If A > &H40 Then A = A - &H7 'A now 58 (&H3A) If B > &H40 Then B = B - &H7 'B remain 49 (&H31) 'Help help help [/code] You might even beable to guess what im doing from that code :D help help help help please! [EDIT] ok, i see why i cant work out how to compute the seeds back now. So, how about computeing the ascii character it pointed to in the 1st place? List: "246789BCDEFGHJKMNPRTVWXZ" being the string and use of InStr() -1 to point to the character. [code] Seed0 = &H32 ascii: 2 Seed1 = &H34 ascii: 4 Seed2 = &H36 ascii: 6 Seed3 = &H37 ascii: 7 Seed4 = &H38 ascii: 8 Seed5 = &H39 ascii: 9 Seed6 = &H42 ascii: B Seed7 = &H43 ascii: C Seed8 = &H44 ascii: D Seed9 = &H45 ascii: E Seed10 = &H46 ascii: F Seed11 = &H47 ascii: G Seed12 = &H48 ascii: H Seed13 = &H4A ascii: J Seed14 = &H4B ascii: K Seed15 = &H4D ascii: M Seed16 = &H4E ascii: N Seed17 = &H50 ascii: P Seed18 = &H52 ascii: R Seed19 = &H54 ascii: T Seed20 = &H56 ascii: V Seed21 = &H57 ascii: W Seed22 = &H58 ascii: X Seed23 = &H5A ascii: Z [/code] Can anyone work this out? And have you guess what im doing now? :) | January 23, 2006, 11:21 AM |
MysT_DooM | yup the formula for private values. and sry have no idea how to help you but check this out i think this might be similar to the algorithm blizz uses. http://en.wikipedia.org/wiki/RSA | January 23, 2006, 4:32 PM |
Ringo | [quote author=MysT_DooM link=topic=13989.msg142855#msg142855 date=1138033953] yup the formula for private values. and sry have no idea how to help you but check this out i think this might be similar to the algorithm blizz uses. http://en.wikipedia.org/wiki/RSA [/quote] Nah, im working on a encode function for d2/d2lod/w2 cdkeys :P [quote="en.wikipedia.org/wiki/RSA"]The algorithm was described in 1977 by Ron Rivest[/quote] lol :) | January 23, 2006, 4:39 PM |
TheMinistered | You should send me a msg on aim, I can probably help you out quite a bit, don't like conversing over forums much ;p | January 23, 2006, 10:35 PM |
Ringo | [quote author=TheMinistered link=topic=13989.msg142887#msg142887 date=1138055708] You should send me a msg on aim, I can probably help you out quite a bit, don't like conversing over forums much ;p [/quote] Thanks! Thats means i got to DL Aim (unless you have MSN) Probly here from me soon :) | January 24, 2006, 10:59 AM |
Adron | Read this as pseudocode or as C++, whichever you prefer. [code] int A, B, flag = 0; const int seed1 = 1, seed2 = 2; A = seed1 * 24 + seed2; if(A >= 0x100) { A = A - 0x100; flag = 1; } B = (A >> 4) + '0'; A = (A & 0x0f) + '0'; if(A > '9') A = A - '9' + 'A' - 1; if(B > '9') B = B - '9' + 'A' - 1; int seed1calc, seed2calc, temp; if(A >= 'A') temp = A - 'A' + 10; else temp = A - '0'; if(B >= 'A') temp += B - 'A' + 10; else temp += B - '0'; if(flag) temp += 0x100; seed1calc = temp / 24; seed2calc = temp % 24; [/code] | January 24, 2006, 4:35 PM |
Ringo | [quote author=Adron link=topic=13989.msg142959#msg142959 date=1138120522] Read this as pseudocode or as C++, whichever you prefer. [code] int A, B, flag = 0; const int seed1 = 1, seed2 = 2; A = seed1 * 24 + seed2; if(A >= 0x100) { A = A - 0x100; flag = 1; } B = (A >> 4) + '0'; A = (A & 0x0f) + '0'; if(A > '9') A = A - '9' + 'A' - 1; if(B > '9') B = B - '9' + 'A' - 1; int seed1calc, seed2calc, temp; if(A >= 'A') temp = A - 'A' + 10; else temp = A - '0'; if(B >= 'A') temp += B - 'A' + 10; else temp += B - '0'; if(flag) temp += 0x100; seed1calc = temp / 24; seed2calc = temp % 24; [/code] [/quote] Hi, thanks! I notice you store a value in flag in order to know if temp has to have 0x100 taken away from it. When encodeing there is no way of knowing if + 0x100 was used :( Iv re-wrote the decode function from existing code, inorder to gain a better understanding of how it works, but its just this last part in the encode function, where the key values get converted back to standard key codes, is where im lost :P Im thinking that re-createing the ascii characters is more possible than re-createing the seed values, due to the lossyness of the method used to convert the ascii characters to hex in the decode function, but this kind of mind blowed me yesterday :P Any ideas? thanks [code] Public Function DecodeD2(ByVal CDKey As String) As String Dim tmpByte As Byte, i%, A&, B& Dim Key(0 To 15) As String Const CodeValues As String = "246789BCDEFGHJKMNPRTVWXZ" For i = 1 To 16 'Fill array Key(i - 1) = UCase(Mid$(CDKey, i, 1)) Next i Dim IntStr%(1), i2% For i = 0 To 15 Step 2 For i2 = 0 To 1 IntStr(i2) = InStr(1, CodeValues, Key(i + i2)) - 1 If IntStr(i2) = -1 Then IntStr(i2) = &HFF If i2 = 0 Then A = IntStr(i2) * 3 Else A = IntStr(i2) + A * 8 Next i2 If A >= &H100 Then A = A - &H100 B = ((RShift(A, 4) And &HF) + &H30) A = ((A And &HF) + &H30) If B > &H39 Then B = B + &H7 If A > &H39 Then A = A + &H7 Key(i) = Chr$(B) Key(i + 1) = Chr$(A) Next i Erase IntStr() Dim tmpD As String * 1 For i = 15 To 0 Step -1 If i > 8 Then tmpByte = ((i - 9) And &HF) Else tmpByte = ((i + 7) And &HF) tmpD = Key(i) Key(i) = Key(tmpByte) Key(tmpByte) = tmpD Next i Dim HashKey& HashKey = &H13AC9741 For i = 15 To 0 Step -1 tmpByte = Asc(UCase(Key(i))) If Val(tmpByte) <= Asc("7") Then Key(i) = Chr$(((HashKey And &HFF) And 7) Xor tmpByte) HashKey = RShift(HashKey, 3) ElseIf Val(tmpByte) < Asc("A") Then Key(i) = Chr$((i And 1) Xor tmpByte) Else Key(i) = Chr$(tmpByte) End If Next i DecodeD2 = Join(Key, vbNullString) Erase Key() End Function [/code] [code] Public Function EncodeD2(ByVal CDKey As String) As String Dim tmpByte As Byte, i%, A&, B& Dim Key(0 To 15) As String Const CodeValues As String = "246789BCDEFGHJKMNPRTVWXZ" For i = 1 To 16 'Fill array Key(i - 1) = UCase(Mid$(CDKey, i, 1)) Next i Dim HashKey& HashKey = &H13AC9741 For i = 15 To 0 Step -1 tmpByte = Asc(UCase(Key(i))) If Val(tmpByte) <= Asc("7") Then Key(i) = Chr$(((HashKey And &HFF) And 7) Xor tmpByte) HashKey = RShift(HashKey, 3) ElseIf Val(tmpByte) < Asc("A") Then Key(i) = Chr$((i And 1) Xor tmpByte) Else Key(i) = Chr$(tmpByte) End If Next i Dim tmpD As String * 1 For i = 0 To 15 If i > 8 Then tmpByte = ((i - 9) And &HF) Else tmpByte = ((i + 7) And &HF) tmpD = Key(i) Key(i) = Key(tmpByte) Key(tmpByte) = tmpD Next i For i = 0 To 15 Step 2 B = Asc(Key(i)) A = Asc(Key(i + 1)) If B > &H40 Then B = B - &H7 If A > &H40 Then A = A - &H7 'uh Next i EncodeD2 = Join(Key, vbNullString) Erase Key() End Function [/code] | January 24, 2006, 4:59 PM |
Adron | If you do not know whether 0x100 was added or not, I think you do not understand the code you are copying. At least not if this is an attempt to work with the W2BNE/D2/etc cd keys. There is no way to map it to two unique seeds without that; you will necessarily have two different and equally possible options. | January 25, 2006, 3:29 PM |
Ringo | [quote author=Adron link=topic=13989.msg143097#msg143097 date=1138202993] If you do not know whether 0x100 was added or not, I think you do not understand the code you are copying. At least not if this is an attempt to work with the W2BNE/D2/etc cd keys. There is no way to map it to two unique seeds without that; you will necessarily have two different and equally possible options. [/quote] I understand it, that is not the problem, the problem is reverseing the effects of it. The only thing im left to do to encode a decoded cdkey into a encoded cdkey again, is to convert the bytes back to key code characters: "246789BCDEFGHJKMNPRTVWXZ" Like for example, if the my cdkey started with "46" it would be classed as 1 and 2 on the 1st loop as you can see below: [code] Const CodeValues As String = "246789BCDEFGHJKMNPRTVWXZ" Dim IntStr%(1), i2% For i = 0 To 15 Step 2 For i2 = 0 To 1 IntStr(i2) = InStr(1, CodeValues, Key(i + i2)) - 1 If IntStr(i2) = -1 Then IntStr(i2) = &HFF If i2 = 0 Then A = IntStr(i2) * 3 Else A = IntStr(i2) + A * 8 Next i2 '//IntStr(0) is 1 from CodeValues string location -1 '//IntStr(1) is 2 from CodeValues string location -1 '//A = 1 * 3 '//A = 2 + A * 8 If A >= &H100 Then A = A - &H100 B = ((RShift(A, 4) And &HF) + &H30) A = ((A And &HF) + &H30) If B > &H39 Then B = B + &H7 If A > &H39 Then A = A + &H7 Key(i) = Chr$(B) Key(i + 1) = Chr$(A) Next i [/code] And unless im missing something which is more than possible with my maths, IntStr(0) and IntStr(1) can not be computed back efficantly, because when there righshifted and and'ed down, bits can be lost. So the only way i see possible to correctly encode the cdkey, is to *some how* compute the characters in CodeValues string, because getting the location in the string where they are from looks impossible. Im not sure if iv ported this to VB6 correctly, but if i have, it shows it to: [code] Dim tmp As Long If A >= Asc("A") Then tmp = A - Asc("A") + 10 Else tmp = A - Asc("0") If B >= Asc("A") Then tmp = tmp + B - Asc("A") + 10 Else tmp = tmp + B - Asc("0") 'If tmp <= &H100 Then tmp = tmp + &H100 A = (tmp / 24) B = (tmp Mod 24) '//A = 0 //If +0x100 A = 11 '//B = 11 //If +0x100 B = 3 [/code] You can test the decode and encode functions out if you want, the decode one works perfectly, and the endcode function unhash the key, reshuffle it back into the correct order, but cant do the converting part :P If im missing somthing can you please explain? Im more than hapy/wanting to learn more. Thanks | January 25, 2006, 4:49 PM |
Adron | When I checked the encoding/decoding of cd keys, the flag indicating whether 0x100 had been subtracted or not was saved into a variable in Blizzard's version of the code. | January 25, 2006, 5:36 PM |
Ringo | Oh, im following now. l)ragon PM'ed me a compleat decode function this morning (thanks l)ragon), and it has the valid check in it. Iv had a hard re-think, and even being able to extract the flag, to know if 0x100 needs to be added or not and knowing where in the key, its looks to be impossible to compute the character locations in the KeyValues string. :( [EDIT]: I just tryed a idea out in the hope i could make a byte array table, but it has become very clear why its not possible :( After making a 24 * 24 table with all possible key values, it shows exacly how much bits are really being lost when the key characters get converted into hex. (I wont post all of it, just the part where it becomes clear) [code] Instr() -1 location of key character Converted hex result Had 0x100 Taken From 00/00 = 0/0 False 00/01 = 1/0 False 00/02 = 2/0 False 00/03 = 3/0 False 00/04 = 4/0 False 00/05 = 5/0 False 00/06 = 6/0 False 00/07 = 7/0 False 00/08 = 8/0 False 00/09 = 9/0 False 00/10 = A/0 False 00/11 = B/0 False 00/12 = C/0 False 00/13 = D/0 False 00/14 = E/0 False 00/15 = F/0 False [/code] [code] 10/16 = 0/0 True 10/17 = 1/0 True 10/18 = 2/0 True 10/19 = 3/0 True 10/20 = 4/0 True 10/21 = 5/0 True 10/22 = 6/0 True 10/23 = 7/0 True 11/00 = 8/0 True 11/01 = 9/0 True 11/02 = A/0 True 11/03 = B/0 True 11/04 = C/0 True 11/05 = D/0 True 11/06 = E/0 True 11/07 = F/0 True [/code] [code] 21/08 = 0/0 True 21/09 = 1/0 True 21/10 = 2/0 True 21/11 = 3/0 True 21/12 = 4/0 True 21/13 = 5/0 True 21/14 = 6/0 True 21/15 = 7/0 True 21/16 = 8/0 True 21/17 = 9/0 True 21/18 = A/0 True 21/19 = B/0 True 21/20 = C/0 True 21/21 = D/0 True 21/22 = E/0 True 21/23 = F/0 True [/code] Is this a loseing battle? :( The only way i can see this to be possible is that the cdkeys them selfs have to be layed out in some kind of order, as in there is another value calced from the other characters (like the KeyFlag) or somthing :-\ Any suggestions/ideas? :( Thanks for helping btw | January 26, 2006, 12:21 PM |
Adron | There is one flag for each pair of letters. Not just one flag for the whole cd key. If that is what you are stuck on. | January 26, 2006, 4:20 PM |
Ringo | [quote author=Adron link=topic=13989.msg143248#msg143248 date=1138292407] There is one flag for each pair of letters. Not just one flag for the whole cd key. If that is what you are stuck on. [/quote] [code] R = 3 For i = 0 To 15 R = R + (GetNumValue(Key(i)) Xor (R * 2)) Next i R = R And &HFF '//flag extracted to R (valid check if decodeing) KeyFlag = &H80 'flag seed Dim tmp& For i = 14 To 0 Step -2 B = Asc(Key(i)) A = Asc(Key(i + 1)) If A >= Asc("A") Then tmp = A - Asc("A") + 10 Else tmp = A - Asc("0") If B >= Asc("A") Then tmp = tmp + B - Asc("A") + 10 Else tmp = tmp + B - Asc("0") If R And KeyFlag Then A = A + &H100 R = R - KeyFlag End If A = (tmp / 24) B = (tmp Mod 24) Key(i) = Mid(CodeValues, B + 1, 1) Key(i + 1) = Mid(CodeValues, A + 1, 1) KeyFlag = KeyFlag / 2 Next i [/code] Iv got that figgerd already, but hows that flag used other than to know if it needs 0x100 taken away? If it isnt, then it leaves a single byte vs 570 somthing possible combinations, making it not possible :( | January 26, 2006, 4:21 PM |
Adron | Well, looking at that code, it seems you have the flag figured fine... | January 26, 2006, 4:32 PM |
Ringo | Hmm, iv thought about it in as many ways as i can, and i *think* each 2 characters can not go any higher than "WC" (21/7) -- 0x1FF, based on how the flag gets calced and space given. If they can go higher than that, then there is no space and its back to square one :( Iv only got around 20 d2/w2 keys, and i did find one with "WC" but non higher, so its kind of shit or bust. :P Thanks for helping Adron, and l)ragon for the compleat decode function. [code] '//flag extract R = 3 For i = 0 To 15 R = R + (GetNumValue(Key(i)) Xor (R * 2)) Next i R = R And &HFF tmpByte = &H80 'seed the flag '//convert hex to KeyCodes For i = 14 To 0 Step -2 A = GetNumValue(Key(i)) B = GetNumValue(Key(i + 1)) A = CLng("&H" & Hex(A) & Hex(B)) If R And tmpByte Then A = A + &H100 Call KeyCodeOffSets(A, B) Key(i) = Mid(KeyCodes, B + 1, 1) Key(i + 1) = Mid(KeyCodes, A + 1, 1) tmpByte = tmpByte / 2 'downgrade flag Next i Private Sub KeyCodeOffSets(Bit1&, Bit2&) Bit2 = 0 While Bit1 >= &H18 Bit2 = Bit2 + 1 Bit1 = Bit1 - &H18 Wend End Sub [/code] | January 26, 2006, 9:02 PM |