Генерация последовательного ха sh UUID - PullRequest
4 голосов
/ 10 января 2020

Я хочу сгенерировать согласованное значение ha sh строки UUID, например dcc549d8-bd0c-49c2-bff8-f6fa80fb7857, предпочтительно число от 0 до N.

Какой самый лучший и быстрый способ сделать это?

Обновление: я думаю об использовании CRC32. Есть плюсы / минусы этого?

Ответы [ 3 ]

5 голосов
/ 10 января 2020

Какого типа sh вы хотели бы? «Лучший» выбор может быть не самым быстрым и зависит от того, для чего вы используете ha sh.

Для md5 вы можете сделать:

var crypto = require('crypto');

var md5sum = crypto.createHash('md5');
md5sum.update(uuid);
var b64 = md5sum.digest('base64')

Затем вы можете использовать библиотеку base64 для преобразования ее в число, если это то, что вам нужно.

Узел шифрования , включая другие алгоритмы хеширования, которые могут быть более подходящими для вашего случая (md5 быстрее, но менее безопасен), документировано здесь: https://nodejs.org/api/crypto.html

4 голосов
/ 14 января 2020

Если подумать о природе UUID пример . Я бы go в этом направлении.

const INIT_NUMBER = 271;

function hash(uuid, N) {
  const x = uuid.split("-").reduce((a,b) => a ^ Number.parseInt(b, 16), INIT_NUMBER) ;
  return arguments.length === 1 ? x : x % N;
}

const a = hash("dcc549d8-bd0c-49c2-bff8-f6fa80fb7857");            
const b = hash("dcc549d8-bd0c-49c2-bff8-f6fa80fb7857", 256);

console.log(a, b);
  
  
0 голосов
/ 19 января 2020

Если вы используете генерацию UUID v4, все цифры, кроме двух, уже содержат псевдослучайные значения, все, что вам нужно сделать, это извлечь их в нужную форму.

Из Spe c:

4.4.  Algorithms for Creating a UUID from Truly Random or
      Pseudo-Random Numbers

   The version 4 UUID is meant for generating UUIDs from truly-random or
   pseudo-random numbers.

   The algorithm is as follows:

   o  Set the two most significant bits (bits 6 and 7) of the
      clock_seq_hi_and_reserved to zero and one, respectively.

   o  Set the four most significant bits (bits 12 through 15) of the
      time_hi_and_version field to the 4-bit version number from
      Section 4.1.3.

   o  Set all the other bits to randomly (or pseudo-randomly) chosen
      values.

Чтобы извлечь псевдослучайные значения, мы просто удаляем первый шестнадцатеричный символ (который содержит 4 старших значащих бита) третьего и четвертого разделов, разделенных "-", и преобразуем его в требуемую базу. Поскольку UUID всегда имеет одинаковую длину, мы можем каждый раз удалять одни и те же индексы (14 и 19).

К сожалению, поскольку Javascript поддерживает только до 32-разрядных целых чисел, нам необходимо указать Number.parseInt Группы из 8 шестнадцатеричных символов (32 бита) отдельно, затем добавьте модули для минимизации смещения.

Поэтому наш код будет:

function parseUUID(uuid, N) {
    var pseudorandomBytes = uuid.substring(0, 14) + uuid.substring(15, 19) + uuid.substring(20); // Splice out the bytes which contain metadata
    pseudorandomBytes = pseudorandomBytes.replace(/-/g, ""); // Remove all dashes
    var accumulator = 0; // Accumulate the sums modulo N of every eight hex characters and the remainder
    pseudorandomBytes.match(/.{1,8}/g).forEach(function (a) { accumulator = (accumulator + (Number.parseInt(a, 16) % N)) % N; });
    return accumulator; // Return the result
}
...