Как подойти к этому в андроиде? подписанный байт

У меня есть часть проблемы, которую я хочу достичь в Android.

Формула

  1. Семя сервера + Клиентское семя (-> байт [4]) + номер ставки (-> байт [4])
  2. Двойной хэш-результат SHA2-512
  3. Продолжайте брать группы по 3 байта и конвертировать в целое число, пока не будет найдено значение менее 16 миллионов. Если у вас закончились байты, попробуйте снова и начните заново.
  4. Найти значение модуля 1 миллион
  5. Модуль - это результат ставки!

У которых есть пример кода в C#

static bool VerifyBetResult(string serverSeed, int clientSeed, int betNumber,
                            long betResult, string serverSeedHash = null)
{
    Func<string, byte[]> strtobytes = s => Enumerable
        .Range(0, s.Length / 2)
        .Select(x => byte.Parse(s.Substring(x * 2, 2), NumberStyles.HexNumber))
        .ToArray();
    byte[] server = strtobytes(serverSeed);
    byte[] client = BitConverter.GetBytes(clientSeed).Reverse().ToArray();
    byte[] num = BitConverter.GetBytes(betNumber).Reverse().ToArray();
    byte[] serverhash = serverSeedHash == null ? null : strtobytes(serverSeedHash);
    byte[] data = server.Concat(client).Concat(num).ToArray();
    using (SHA512 sha512 = new SHA512Managed())
    {
        if (serverhash != null)
            using (SHA256 sha256 = new SHA256Managed())
                if (!sha256.ComputeHash(server).SequenceEqual(serverhash))
                    throw new Exception("Server seed hash does not match server seed");
        byte[] hash = sha512.ComputeHash(sha512.ComputeHash(data));
        while (true)
        {
            for (int x = 0; x <= 61; x += 3)
            {
                long result = (hash[x] << 16) | (hash[x + 1] << 8) | hash[x + 2];
                if (result < 16000000)
                    return result % 1000000 == betResult;
            }
            hash = sha512.ComputeHash(hash);
        }
    }
}

Используя эти значения

serverSeed = e600f76aa6c520dff7db34559bd05cb1048b1830a07cd81844147a19048fc9be;
clientSeed = 443944;
betNumber = 0;
serverHash = ca90022ac66a6a77d8b5072e101bff505c2bff552b1b9a0785f0c438d5b6228f;

Я хочу найти (результат% 1000000), который должен быть = 563383

Но я получил -25564 и serverHash не соответствует serverSeed при хэшировании семени для sha256

Обновление Это мой код:

private byte[] reverse(byte[] b){
    int i = b.length - 1;
    byte newB[] = new byte[4];
    for(int x = 0; x < b.length; x++){
        newB[x] = b[i];
        i--;
    }
    return newB;
}

private byte[] strToByte(String s) {
    int len = s.length();
    byte[] data = new byte[len/2];

    for(int i = 0; i < len; i+=2){
        data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

private long verifyBet(){
    //MessageDigest md256 = null;
    MessageDigest md512 = null;
    try {
        //md256 = MessageDigest.getInstance("SHA-256");
        md512 = MessageDigest.getInstance("SHA-512");
    } catch (Exception e) {
        e.printStackTrace();
    }
    String //res = "ServerSeed = ",
        sSeed = "e600f76aa6c520dff7db34559bd05cb1048b1830a07cd81844147a19048fc9be";
        //sHash = "ca90022ac66a6a77d8b5072e101bff505c2bff552b1b9a0785f0c438d5b6228f";
    int cSeed = 443944,
        num = 0;
    byte serverSeed[] = strToByte(sSeed),
        //serverHash[] = strToByte(sHash),
        clientSeed[] = reverse(ByteBuffer.allocate(4).putInt(cSeed).array()),
        betNumber[] = reverse(ByteBuffer.allocate(4).putInt(num).array());
    byte data[] = ByteBuffer.allocate(serverSeed.length + clientSeed.length + betNumber.length)
        .put(serverSeed).put(clientSeed).put(betNumber).array();
    data = md512.digest(data);
    data = md512.digest(data);
    long secret = 0;
    boolean found = false;
    while(!found){
        for(int x = 0; x <= 61; x += 3){
            long result = (data[x] << 16 | data[x+1] << 8) | data[x+2];
            if (result < 16000000){
                secret = result % 1000000;
                found = true;
            }
        }
        data = md512.digest(data);
    }
    return secret;
}

После гораздо большего исследования я обнаружил, что byte в java является signed в то время как код, на котором я базируюсь, вычисляет в unsignedbyte вот почему я получаю результат в отрицательный..

Как я могу получить набор байтов в "беззнаковой" форме?

1 ответ

После стольких исследований и испытаний. Я наконец получил это. Это код.

private byte[] strToByte(String s) {
    int len = s.length();
    byte[] data = new byte[len/2];

    for(int i = 0; i < len; i+=2){
        data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

private long verifyBet(int _num){
    MessageDigest md512 = null;
    try {
        md512 = MessageDigest.getInstance("SHA-512");
    } catch (Exception e) {
        e.printStackTrace();
    }
    String sSeed = "e600f76aa6c520dff7db34559bd05cb1048b1830a07cd81844147a19048fc9be";
    int cSeed = 443944,
        num = _num;
    byte serverSeed[] = strToByte(sSeed),
        clientSeed[] = ByteBuffer.allocate(4).putInt(cSeed).array(),
        betNumber[] = ByteBuffer.allocate(4).putInt(num).array();
    byte data[] = ByteBuffer.allocate(serverSeed.length + clientSeed.length + betNumber.length)
        .put(serverSeed).put(clientSeed).put(betNumber).array();
    data = md512.digest(data);
    data = md512.digest(data);
    long secret = 0;
    boolean found = false;
    while(!found){
        for(int x = 0; x <= 61; x += 3){
            long result = ((data[x] & 0xFF) << 16 | (data[x+1] & 0xFF) << 8) | data[x+2] & 0xFF;
            if (result < 16000000){
                secret = result % 1000000;
                found = true;
                x = 62;
            }
        }
        data = md512.digest(data);
    }
    return secret;
}
Другие вопросы по тегам