byte [] до 0x шестнадцатеричной строки с fnv1a32 - PullRequest
2 голосов
/ 22 сентября 2019

Я пытаюсь перенести следующий код Python на c #

import os
import sys
import ctypes

FNV32_PRIME = 0xB3CB2E29
FNV32_BASIS = 0x319712C3

def uint32(v):
  return ctypes.c_uint32(v).value

def fnv1a_hash(data):
  hval = FNV32_BASIS

  for i in range(0, len(data)):
    hval = uint32(hval ^ data[i])
    hval = uint32(hval * FNV32_PRIME)

  return hval

print("starting")

if len(sys.argv) == 2:
  input_file_path = sys.argv[1]
else: input_file_path = "dvars.txt"

with open(input_file_path, "r") as input_file:
    for dvar_name in input_file:
      dvar_name = dvar_name.rstrip("\r\n")
      dvar_hash_1 = dvar_name.lower() + '\x00'
      dvar_hash_2 = bytearray(dvar_hash_1.encode("ascii"))
      dvar_hash = fnv1a_hash(dvar_hash_2)
      final = "%-30s = 0x%08X" % (dvar_name, dvar_hash)
      print(final)
print("done")

, который работает нормально:

starting
con_gameMsgWindow0MsgTime      = 0xFC60C821

Я получил это до сих пор:

    public static class Extensions
    {
        private const UInt32 FnvPrime = 0xB3CB2E29;private const UInt32 FnvOffsetBasis = 0x319712C3;
        public static string ToHashFnv1a32(this string text, Fnv1a32 hasher = null)
        {
            var bytes_encoded = Encoding.UTF8.GetBytes(text); // +'\x00'
            if (hasher is null) hasher = new Fnv1a32(fnvPrime: FnvPrime, fnvOffsetBasis: FnvOffsetBasis);
            var byte_hash = hasher.ComputeHash(bytes_encoded);
            // int decValue = int.Parse(t, System.Globalization.NumberStyles.HexNumber);
            var uint32 = BitConverter.ToUInt32(byte_hash, 0);
            var uint32_hex = string.Format("{0:X}", uint32);
            var uint32_dec = string.Format("{0:D}", uint32);
            var stringg = BitConverter.ToString(byte_hash).Replace("-", "");
            var expected_hex = string.Format("{0:X}", 0xFC60C821);
            var expected_dec = string.Format("{0:D}", 0xFC60C821);
            return byte_hash.ToString(); // 
        }
    }

но по какой-то причине я получаю самые странные результаты:

    text    "con_gameMsgWindow0LineCount"   string
    hasher  {Fnv1a.Fnv1a32} Fnv1a.Fnv1a32
    bytes_encoded   {byte[0x0000001b]}  byte[]
    byte_hash   {byte[0x00000004]}  byte[]
    uint32  0x0a65c1a8  uint
    uint32_hex  "A65C1A8"   string
    uint32_dec  "174440872" string
    stringg "A8C1650A"  string
    expected_hex    "FC60C821"  string
    expected_dec    "4234201121"    string

Я действительно бьюсь головой о стол, потому что не могу понять, почему он не вычисляет правильный хеш (яиспользуя измененную версию https://github.com/jslicer/FNV-1a, чтобы я мог изменить базу и смещение)

1 Ответ

2 голосов
/ 22 сентября 2019

Сам хэш FNV1a работает в C # -коде.Однако C # -код отличается от Python-кода следующими моментами в отношении обработки входных данных:

  • C # -код не удаляет \r\n в конце.
  • C # -код не преобразуется в строчные буквы.
  • 0-байт не добавляется в C # -код.

Кроме того, C # -код нене используйте текст con_gameMsgWindow0MsgTime, но con_gameMsgWindow0LineCount.

Решение заключается в добавлении следующей строки в начале ToHashFnv1a32 -метода C # -кода:

text = text.TrimEnd('\r', '\n').ToLower() + "\0";

и, конечно, одинаковые данные должны использоваться в обоих кодах для теста.

Примечание: основа и смещение, используемые в Python-коде, отличаются от обычно используемых значений .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...