2011-03-13 2 views
2

Я занимаюсь кэшированием через javascript. У меня есть метод, который принимает массив строк и возвращает обработанный результат. Я хочу создать уникальный идентификатор из этих строк, а затем использовать его как ключ в объекте для хранения результата. Таким образом, ключи в кеше занимают как можно меньше памяти.Создание уникального идентификатора из массива строк в javascript?

В сущности, я хочу что-то вроде SHA1, но для javascript.

Любая идея, как я могу это сделать?

Спасибо.

ответ

-1

Может быть, это:

var newDate = new Date; 
var uid = newDate.getTime(); 

или это:

var uid = Math.random() * Math.pow(10, 17) + Math.random() * Math.pow(10, 17) + Math.random() * Math.pow(10, 17) + Math.random() * Math.pow(10, 17)); 

Есть много способов получить то, как близко, как уникальный идентификатор, и так как вы работаете с JavaScript для кэширования, это становится легче. Это вопрос выбора того, что лучше всего подходит вам.

+0

Очень яркий, с большой вероятностью создаст повторяющиеся идентификаторы, предоставленные нескольким пользователям, и т. Д. Не очень хорошее решение. –

+0

Я также хочу, чтобы это возвращало тот же идентификатор, что и значение. Отсюда ссылка на Ша1. –

+1

@Marc B: javascript не является общим, без проблем с несколькими пользователями, в зависимости от его глубокой цели. – yoda

0

Вы хотите sha1 в JavaScript? Здесь ->http://pajhome.org.uk/crypt/md5/sha1.html

+0

Да, этого я и хотел избежать. Этот код выглядит очень тяжелым. Мне также нравится использовать полные строки, поскольку ключ будет более эффективным, чем использование этого. –

1

Без использования хэша вы не получите что-то уникальное и маленькое.

Выполнение myArray.join()май гарантия уникальная, но может потреблять большой объем памяти и сталкиваться с краями, где она не будет уникальной.

Лучше всего использовать реализацию алгоритма хэширования в JavaScript.

+0

Технически, в зависимости от строк, 'myArray.join()' даже не гарантирует уникальность. Например, '['a', 'b', 'c']. Join() === ['a', 'b, c']. Join()'. Если строки находятся в определенном формате, это может быть достаточно хорошим (но без экономии пространства он ищет, как вы сказали). –

+0

@Matthew Да, спасибо за это, я не рассматривал это. Я сделаю обновление. – alex

+0

Это то, что я сейчас делаю. И я присоединяюсь к токену, чтобы предотвратить конфликт. Но, как вы сказали, у меня есть некоторые случаи, в результате которых получается более 5000 символов. Просто похоже на чрезмерную длину ключа. –

1

В зависимости от характера значений в массивах вы можете приготовить что-то быстрое и подходящее для вашего случая. Также важно подумать о том, каковы шансы столкновения и каковы его последствия. Поскольку мы не в настоящее время всю эту информацию, я могу только предоставить некоторые отправные точки для работы с:

  1. Если конкатенация строк, как ожидается, будет «долго», вы хотите использовать какой-то «hash», который возвращает более короткое значение.
  2. Вы, наверное, не нужно криптографически силы хэш, так md5 или sha1, вероятно, слишком
  3. Даже низкотехнологичное, быстрые хэши как (length of string concat as int) + '/' + (number of strings as int) + '/' + (first char of each string) может быть штраф в зависимости от ожидаемых значений

Наконец, вот реализация string.GetHashCode() портирована с C#. Если это хорошо для .NET, это, вероятно, достаточно для вас.

var str = "concatenation of all array values"; 
var hash1 = (5381<<16) + 5381; 
var hash2 = hash1; 
var hashPos = 0; 
while(hashPos < str.length) { 
    hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27))^str.charCodeAt(hashPos); 
    if(hashPos == str.length - 1) { 
     break; 
    } 
    hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27))^str.charCodeAt(hashPos + 1); 
    hashPos += 2; 
} 

return hash1 + (hash2 * 1566083941); 
+0

Определенно интересное решение. Я сделаю это и посмотрю, как это работает. Я согласен с тем, что всегда происходит небольшое изменение, которое может повредить, но в моем случае это крайне редко, поскольку кеш хранится в переменной экземпляра через javascript, независимо от каждого пользователя, и он перезагружается по каждому запросу. –

3

К сожалению, нет возможности получить 100% гарантированную уникальность без использования всего содержимого массива в качестве ключа. Самые хорошие, не криптографические хэши будут только уменьшать коллизии до суммы, приемлемой для хорошей производительности в хеш-таблице, но вам все равно нужно проверить соответствие всего содержимого.

Даже криптографический хеш, такой как SHA-1 или MD5, все еще может иметь столкновения, но в большинстве случаев это крайне маловероятно. Если это будет достаточно хорошо, я, вероятно, поеду с SHA-1. В противном случае я бы преобразовал массив в строку, которая будет использоваться в качестве ключа, и пусть JavaScript беспокоится о хэшировании и конфликтах.

В любом случае, вы, вероятно, работаете с производительностью (собственное хэширование, которое делает JavaScript, вероятно, будет намного быстрее, чем все, что вы можете писать на JavaScript) и, возможно, абсолютную правильность для пространства.

Кроме того, независимо от того, выполняете ли вы сами хеширование или выполняете JavaScript, будьте осторожны с тем, как вы преобразовываете массив в строку, потому что простая конкатенация может быть не уникальной (даже с разделителем).

+0

+1 Правильное и информативное. – alex

Смежные вопросы