Created
November 22, 2012 20:55
-
-
Save soulcyon/4132890 to your computer and use it in GitHub Desktop.
Halo Decoding CD Key
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* decodeCDKey (11/21/2012) | |
* | |
* Taking the registry entry from Halo, this function can decode the entry back into the original | |
* CD Key. One must procure this entry through an alternative program, such as regedit or a batch | |
* script. Navigate to registry folder "HKLM\SOFTWARE\Microsoft\Microsoft Games\Halo" | |
* Open the key "DigitalProductID" and copy the 72nd byte to 96th byte. Make sure there are zeroes | |
* surrounding this section of bytes. Reverse the bytes and send to decodeCDKey($in). | |
* | |
* Try with sample input: decodeCDKey("012405bd55dd2af6e7abc5915de144") | |
* Expected output should be: GQV8J-73GC2-RQ2K2-C82HJ-PX2Q6 | |
* | |
* @author Sashank Tadepalli <dijjit@gmail.com> | |
* @license Creative Commons Attribution 3.0 Unported License. | |
* @version 1.0 | |
* @link http://dijjit.com/halo/decoding-halo-cd-key/ | |
*/ | |
function decodeCDKey($in){ | |
// Initial character arrays for base conversion and replacing | |
$search = str_split('0123456789abcdefghijklmn'); | |
// Uppercase for Microsoft styling | |
$replace = str_split('BCDFGHJKMPQRTVWXY2346789'); | |
// Check for gmp_init, to speed up base conversion | |
if( function_exists('gmp_init') ){ | |
$result = gmp_strval(gmp_init($in, 16), 24); | |
} else { | |
$result = base_conv($in, $search, str_split('0123456789abcdef')); | |
} | |
// Manually replace each character in sequence | |
for( $i = 0;$i < 25; $i++ ){ | |
$result{$i} = $replace[array_search($result{$i}, $search)]; | |
} | |
// Add the infamous Microsoft hyphens | |
return substr($result, 0, 5) . "-" . substr($result, 5, 5) . "-" . | |
substr($result, 10, 5) . "-" . substr($result, 15, 5) . "-" . | |
substr($result, 20, 5); | |
} | |
/* Thanks Core Xii, http://stackoverflow.com/questions/352434/ */ | |
function base_conv($val, &$baseTo, &$baseFrom){ | |
return base_arr_to_str( | |
base_conv_arr(base_str_to_arr($val, $baseFrom), count($baseTo), count($baseFrom)), | |
$baseTo); | |
} | |
function base_conv_arr($val, $baseToDigits, $baseFromDigits){ | |
$valCount = count($val); | |
$result = array(); | |
do { | |
$divide = 0; | |
$newlen = 0; | |
for( $i = 0; $i < $valCount; ++$i ){ | |
$divide = $divide * $baseFromDigits + $val[$i]; | |
if( $divide >= $baseToDigits ){ | |
$val[$newlen ++] = (int) ($divide / $baseToDigits); | |
$divide = $divide % $baseToDigits; | |
} else if( $newlen > 0 ){ | |
$val[$newlen ++] = 0; | |
} | |
} | |
$valCount = $newlen; | |
array_unshift($result, $divide); | |
} | |
while ($newlen != 0); | |
return $result; | |
} | |
function base_arr_to_str($arr, &$base){ | |
$str = ''; | |
foreach( $arr as $digit ){ | |
$str .= $base[$digit]; | |
} | |
return $str; | |
} | |
function base_str_to_arr($str, &$base){ | |
$arr = array(); | |
while( $str === '0' || !empty($str) ){ | |
foreach( $base as $index => $digit ){ | |
if( mb_substr($str, 0, $digitLen = mb_strlen($digit)) === $digit ){ | |
$arr[] = $index; | |
$str = mb_substr($str, $digitLen); | |
continue 2; | |
} | |
} | |
throw new Exception(); | |
} | |
return $arr; | |
} | |
echo decodeCDKey("012405bd55dd2af6e7abc5915de144"); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment