Существует ли алгоритм хэширования, который создает размер хэша в 64 бита в C #? - PullRequest
3 голосов
/ 03 декабря 2010

Мне нужно создать значение Hash на основе строки переменной длины, которую я могу хранить в поле не более 16 (из-за требований поставщика).

Я объединяю несколько строк, которые передаются через преобразование сценария C # для вычисления хэша.Я ограничен спецификацией файла поставщика в том смысле, что вывод хеша не может быть длиннее 16.

У кого-нибудь есть какие-либо предложения?Например, строковое преобразование алгоритма MD5 имеет длину 32.

Ответы [ 5 ]

7 голосов
/ 03 декабря 2010

Криптография имеет функции, разработанные таким образом, что вы можете обрезать вывод до некоторого размера, а усеченная хеш-функция остается безопасной криптографической хеш-функцией. Например, если вы возьмете первые 128 бит (16 байтов) вывода SHA-512, примененного к некоторому входу, то первые 128 бит будут криптографическим хешем, таким же сильным, как любой другой 128-битный криптографический хеш.

Решение состоит в том, чтобы выбрать некоторую криптографическую хеш-функцию - SHA-256, SHA-384 и SHA-512 - хороший выбор - и усекает вывод до 128 бит (16 байт).

- EDIT -

Исходя из комментария о том, что значение хеш-функции при кодировании в ASCII должно соответствовать 16 символам ASCI, решение имеет значение

  • сначала выберите некоторую криптографическую хеш-функцию (семейство SHA-2 включает SHA-256, SHA-384 и SHA-512)
  • затем, чтобы усечь вывод выбранной хеш-функции до 96 бит (12 байтов) - то есть сохранить первые 12 байтов вывода хеш-функции и отбросить оставшиеся байты
  • затем для кодирования base-64 усеченного вывода до 16 символов ASCII (128 бит)
  • Эффективно выдавая 96-битный криптографический хеш.
0 голосов
/ 15 февраля 2016

Я заметил, что этот вопрос относительно старый, но я уверен, что кто-то посчитает этот ответ ценным.

Мое предложение будет использовать Blake2b, который может использовать от 8 до 512 бит. Если размер ключа не используется, в этом случае используется значение по умолчанию «512». Значение по умолчанию Blake2s 256 бит.

        // BLAKE2b
        // using System.Data.HashFunction;
        //
        // String message to use.
        string str = "The quick brown fox jumps over the lazy dog";
        // Initialize
        System.Data.HashFunction.Blake2B Blake2B = new System.Data.HashFunction.Blake2B();
        // Get string hash bytes; create 64 bit hash.
        var HashBytes = Blake2B.ComputeHash(str, 64);
        // Convert bytes to string and remove the dashes.
        string hexString = BitConverter.ToString(HashBytes).Replace("-", string.Empty);
        // Display results.
        MessageBox.Show(hexString);
        /*
         * "The quick brown fox jumps over the lazy dog" produces a hash value of
         * "A8ADD4BDDDFD93E4877D2746E62817B116364A1FA7BC148D95090BC7333B3673F82401CF7AA2E4CB1ECD90296E3F14CB5413F8ED77BE73045B13914CDCD6A918"
         * and "2FD0F3FB3BD58455" hash for 64 bits.
         */

Надеюсь, это поможет!

0 голосов
/ 22 сентября 2015

Есть комментарии к этому коду? Кажется, работает хорошо ...

var p = new MD5CryptoServiceProvider();
var dic = new Dictionary<long, string>();

for (var i = 0; i < 10000000; i++)
{
    if (i%25000 == 0)
        Console.WriteLine("{0:n0}", i);

    var h = p.ComputeHash(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));
    var b = BitConverter.ToInt64(h, 0);

    // "b" is hashed Int64

    if (!dic.ContainsKey(b))
        dic.Add(i, null);
    else
        throw new Exception("Oops!");
}
0 голосов
/ 03 декабря 2010

Для этого вы можете легко использовать хеш MD5, но вам придется изменить способ его хранения.MD5 является 128-битным, что обычно отображается как 32 4-битных (шестнадцатеричных) значения.Стандартный символ равен 8 битам, поэтому 16 символов достаточно для хранения значения хеша MD5.

Чтобы преобразовать его, попробуйте следующее:

String hash32 = "d41d8cd98f00b204e9800998ecf8427e"
String hash16 = ""

for(int i = 0; i < 32; i+=2)
{
  uint high = Convert.ToUInt32(hash32[i], 16);
  uint low = Convert.ToUInt32(hash32[i+1], 16);
  char c = (char) ((high << 4) | low);

  hash16 += c;
}
0 голосов
/ 03 декабря 2010

Если у вас есть 16 байтов, хранение 128-битного числа не является проблемой. Сохраните 128-битное значение как 16-байтовое значение вместо строки из 32 символов, в которой 16-байтовое значение сохранено как HEX.

В качестве примечания я использовал поля GUID / UUID в базах данных для хранения хэшей MD5. Хотя более не криптографически безопасны, 128-битные MD5-хэши подходят для контрольных сумм (и намного лучше, чем 64-битные.)

var result = MD5.Create().ComputeHash(new byte[] { 0 });

Console.WriteLine(result.Length);
Console.WriteLine(Convert.ToBase64String(result));
Console.WriteLine(result.Aggregate(new StringBuilder(),
                                    (sb, v) => sb.Append(v.ToString("x2"))));

//16
//k7iFrf4NoInN9jSQT9WfcQ==
//93b885adfe0da089cdf634904fd59f71

File.WriteAllBytes("tempfile.dat", result);

var input = File.ReadAllBytes("tempfile.dat");

Console.WriteLine(input.Length);
Console.WriteLine(Convert.ToBase64String(input));
Console.WriteLine(input.Aggregate(new StringBuilder(), 
                                    (sb, v) => sb.Append(v.ToString("x2"))));

//16
//k7iFrf4NoInN9jSQT9WfcQ==
//93b885adfe0da089cdf634904fd59f71

Обратите внимание, что я не показываю содержимое файла, потому что есть большая вероятность, что оно будет содержать "непечатные" символы.

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