Подтвердить что ты не робот

Какой лучший способ создать короткий хеш, похожий на то, что делает крошечный URL?

В настоящее время я использую хэши MD5, но я хотел бы найти что-то, что создаст более короткий хеш, который использует только [a-z][A-Z][0-9]. Это должно быть около 5-10 символов.

Есть ли что-то, что уже делает это?

Обновление 1:

Мне нравится хэш CRC32. Есть ли чистый способ расчета в .NET?

Обновление 2:

Я использую функцию CRC32 по предоставленной Джо ссылке. Как я могу преобразовать UInt в символы, определенные выше?

4b9b3361

Ответ 1

Строковый объект .NET имеет функцию GetHashCode(). Он возвращает целое число. Преобразуйте его в шестнадцатеричный, а затем в строку длиной 8 символов.

Так же:

string hashCode = String.Format("{0:X}", sourceString.GetHashCode());

Подробнее об этом: http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx

ОБНОВЛЕНИЕ: Добавлены замечания из приведенной выше ссылки на этот ответ:

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

Если два строковых объекта равны, метод GetHashCode возвращает идентичные значения. Однако не существует уникального значения хеш-кода для каждое уникальное строковое значение. Различные строки могут возвращать один и тот же хэш код.

Примечания к вызывающим абонентам

Значение, возвращаемое GetHashCode, зависит от платформы. Он отличается 32-разрядные и 64-разрядные версии .NET Framework.

Ответ 2

Ваша цель создать сокращение URL или создать хеш-функцию?

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

Вы можете сделать это, используя следующий код:

using System.Security.Cryptography;

const int numberOfNumbersNeeded = 100;
const int numberOfBytesNeeded = 8;
var randomGen = RandomNumberGenerator.Create();
for (int i = 0; i < numberOfNumbersNeeded; ++i)
{
     var bytes = new Byte[numberOfBytesNeeded];
     randomGen.GetBytes(bytes);
}

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

Затем вы можете преобразовать 8-байтовое случайное число в строку, используя символы в алфавите. Это в основном изменение базового расчета (от основания 256 до базы 62).

Ответ 3

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

Ответ 4

Просто возьмите Base36 (без учета регистра) или Base64 идентификатора записи.

Итак, скажем, я хотел использовать Base36:

(ID - Base36)
1 - 1
2 - 2
3 - 3
10 - A
11 - B
12 - C
...
10000 - 7PS
22000 - GZ4
34000 - Q8C
...
1000000 - LFLS
2345000 - 1E9EW
6000000 - 3KLMO

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

Ответ 5

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

TinyURL.com кажется, использует увеличенное число, которое преобразуется в База 36 (0-9, AZ).

Ответ 6

Вы можете уменьшить количество символов из хеша MD5, закодировав их как буквенно-цифровые символы. Каждый символ MD5 обычно представляется как шестнадцатеричный, так что 16 возможных значений. [a-zA-Z0-9] содержит 62 возможных значения, поэтому вы можете кодировать каждое значение, взяв 4 значения MD5.

EDIT:

здесь функция, которая принимает число (4 шестнадцатеричных цифры) и возвращает [0-9a-zA-Z]. Это должно дать вам представление о том, как его реализовать. Обратите внимание, что могут возникнуть некоторые проблемы с типами; Я не тестировал этот код.

char num2char( unsigned int x ){
    if( x < 26 ) return (char)('a' + (int)x);
    if( x < 52 ) return (char)('A' + (int)x - 26);
    if( x < 62 ) return (char)('0' + (int)x - 52);
    if( x == 62 ) return '0';
    if( x == 63 ) return '1';
}

Ответ 7

Сначала я получаю список случайных чисел. Затем я выбираю каждый char из базовой строки, добавляю и возвращаю результат. Я выбираю 5 символов, которые будут состоять из 6471002 перестановок из базы 62. Вторая часть - проверить против db, чтобы увидеть, существует ли какой-либо файл, если не сохранить короткий URL.

 const string BaseUrlChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

 private static string ShortUrl
 {
     get
     {
         const int numberOfCharsToSelect = 5;
         int maxNumber = BaseUrlChars.Length;

         var rnd = new Random();
         var numList = new List<int>();

         for (int i = 0; i < numberOfCharsToSelect; i++)
             numList.Add(rnd.Next(maxNumber));

         return numList.Aggregate(string.Empty, (current, num) => current + BaseUrlChars.Substring(num, 1));
      } 
  }

Ответ 8

Вы можете использовать CRC32, длина 8 байтов и аналогична MD5. Уникальные значения будут поддерживаться путем добавления метки времени к фактическому значению.

Таким образом, он будет выглядеть как http://foo.bar/abcdefg12.

Ответ 9

Если вы ищете библиотеку, которая генерирует крошечные уникальные хэши из интервала, я могу настоятельно рекомендовать http://hashids.org/net/. Я использую его во многих проектах, и он работает фантастически. Вы также можете указать свой собственный набор символов для пользовательских хэшей.

Ответ 10

Если вам не нужна сила криптографии, любая из функций CRC будет делать.

Wikipedia содержит список различных хеш-функций, включая длину вывода. Преобразование их вывода в [a-z] [A-Z] [0-9] тривиально.

Ответ 11

Вы можете кодировать хэш-код md5 с помощью base64 вместо шестнадцатеричного, таким образом вы получите более короткий URL-адрес, используя именно символы [a-z] [A-Z] [0-9].

Ответ 12

Там есть замечательная, но древняя программа, называемая btoa, которая преобразует двоичный код в ASCII, используя буквы верхнего и нижнего регистра, цифры и два дополнительных символа. Также кодирование MIME base64; большинство Linux-систем, вероятно, имеют программу под названием base64 или base64encode. Либо один даст вам короткую, читаемую строку из 32-битного CRC.

Ответ 13

Вы можете взять первые буквенно-цифровые 5-10 символов хеша MD5.