Я пытаюсь проверить посылку, отправленную мне с сервера. семя используется для перетасовки колод карт с MersenneTwister. В конце игры колода карт отправляется мне с сервера, чтобы я мог проверить колоду с семенем.
Я знаю, что у меня правильное начальное число, но после хэширования я получаю другую колоду, чем та, которую предоставляет сервер.
Я пробовал все виды кодирования текста, ни одна комбинация не дает ту же колоду, которую я получаю с сервера. Я знаю, что они используют SHA от http://caligatio.github.com/jsSHA/, возможно, где-то там ошибка?
// Next, perform the shuffle on a deck of cards and verify the deck is exactly the one that we got.
// 1. Python's random module first hashes the game seed using SHA
// 2. The hash is turned into a sequence of bytes
// 3. The bytes are appended to the seed
// 4. The result is used to seed a Mersenne Twister
// Concat the original seed with the hash of the seed
var hash_bytes = new Array()
for( var i = 0; i < game_info_package.game_seed.length; i++ ) {
hash_bytes.push(game_info_package.game_seed.charCodeAt(i));
}
var hashed_game_seed = (new jsSHA(game_info_package.game_seed, "ASCII")).getHash("SHA-512", "HEX");
for( var i = 0; i < 128; i += 2 ) {
hash_bytes.push(parseInt(hashed_game_seed.substring(i, i+2), 16));
}
// Convert the hash_bytes into an array of 32-bit words starting from the right
var word_array = byte_array_to_words(hash_bytes);
// Create a MT rng
var twister = new MersenneTwister();
twister.init_by_array(word_array, word_array.length);
// At this point we need to shuffle the deck (it must match the one on the server or else we'll get the wrong answer)
var check_cards = new Array();
for( var deck = 0; deck < this.RULESET['number_of_decks']; deck++ ) {
check_cards = check_cards.concat(this.STANDARD_CARDS.slice(0));
}
shuffle(twister, check_cards)
check_cards_string = check_cards.join("");
// Get the deck out of the deal_hash_source (deck should be part of the game hash)
var first_close_paren = game_info_package.deal_hash_source.indexOf(')');
var game_cards = game_info_package.deal_hash_source.slice(1, first_close_paren);
// This verifies the deck order hasn't changed
if( check_cards_string == game_cards ) {//...}
List<byte> hash_bytes = new List<byte>();//all bytes
byte[] seedbytes = System.Text.Encoding.BigEndianUnicode.GetBytes( game_seed );
foreach(byte b in seedbytes){
hash_bytes.Add(b);
}
//1. hashes the game seed using SHA
byte[] bytes = System.Text.Encoding.BigEndianUnicode.GetBytes( game_seed );
SHA512 sha = SHA512.Create();
byte[] hashed_ = sha.ComputeHash(bytes);//2. The hash is turned into a sequence of bytes
//append to hash_bytes
foreach(byte b in hashed_){
hash_bytes.Add(b);
}
//List -> Array
byte[] _bytes = new byte[hash_bytes.Count];
for(int i = 0; i < hash_bytes.Count; i++){
_bytes[i] = hash_bytes[i];
}
// Convert the hash_bytes into an array of 32-bit words starting from the right
uint[] word_array = byte_array_to_words_fromright(_bytes);
// Create a MT rng
//MersenneTwister.RandomMersenne twister;
RandomMersenne twister = new RandomMersenne();
twister.RandomInitByArray(word_array, word_array.Length);
// At this point we need to shuffle the deck (it must match the one on the server or else we'll get the wrong answer)
string[] check_cards = new string[(STANDARD_CARDS.Length * numberofdecks)];
string deckcheckstring = "";
for( int deck = 0; deck < numberofdecks; deck++ ) {
for(int i = 0; i<52; i++){
int cardspace = (deck*52) + i;
check_cards[cardspace] = STANDARD_CARDS[i];
deckcheckstring += check_cards[cardspace];
}
}
//Debug.Log(deckcheckstring);
string[] shuf = shuffle(twister, check_cards);
Оба блока кода должны давать одинаковую случайную последовательность