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

Вычислить контрольную сумму для строки

Я получил строку произвольной длины (допустим, от 5 до 2000 символов), которую я бы хотел вычислить для контрольной суммы.

Требования

  • Та же контрольная сумма должна быть возвращена каждый раз, когда вычисление выполняется для строки
  • Контрольная сумма должна быть уникальной (без столкновений)
  • Я не могу хранить предыдущие идентификаторы для проверки на наличие конфликтов.

Какой алгоритм я должен использовать?

Обновление:

  • Есть ли подход, который является разумным уникальным? то есть вероятность столкновения очень мала.
  • Контрольная сумма должна быть буквенно-цифровой
  • Строки являются unicode
  • Строки - это фактически тексты, которые должны быть переведены, и контрольная сумма хранится при каждом переводе (так что переведенный текст можно сопоставить с исходным текстом).
  • Длина контрольной суммы для меня не важна (чем короче, тем лучше)

Update2

Скажем, что я получил следующую строку "Welcome to this website. Navigate using the flashy but useless menu above".

Строка используется в представлении аналогично gettext в linux. то есть пользователь просто пишет (в режиме бритвы)

@T("Welcome to this website. Navigate using the flashy but useless menu above")

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

4b9b3361

Ответ 1

Это невозможно.

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

Обновление:

Термин "разумно уникальный" не имеет смысла, либо он уникален, либо нет.

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

Алгоритм MD5, например, создает 16-байтовый хэш-код. Преобразуйте строку в массив байтов, используя некоторую кодировку, которая сохраняет все символы, например UTF-8, вычисляет хэш-код с помощью класса MD5, а затем преобразует массив байтов хеш-кода в строку, используя класс BitConverter:

string theString = "asdf";

string hash;
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create()) {
  hash = BitConverter.ToString(
    md5.ComputeHash(Encoding.UTF8.GetBytes(theString))
  ).Replace("-", String.Empty);
}

Console.WriteLine(hash);

Вывод:

912EC803B2CE49E4A541068D495AB570

Ответ 2

Для этого можно использовать криптографические функции хэша. Большинство из них доступны в .Net

Например:

var sha1 = System.Security.Cryptography.SHA1.Create();
byte[] buf = System.Text.Encoding.UTF8.GetBytes("test");
byte[] hash= sha1.ComputeHash(buf, 0, buf.Length);
//var hashstr  = Convert.ToBase64String(hash);
var hashstr = System.BitConverter.ToString(hash).Replace("-", "");

Ответ 3

Примечание. Это ответ на исходный вопрос.

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

Контрольная сумма должна быть уникальной (без столкновений)

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

Ответ 4

Я понимаю, что этот пост практически древний, но я наткнулся на него и столкнулся с почти идентичным вопросом в прошлом. У нас было поле nvarchar (8000), которое нам нужно было искать.

Наше решение состояло в том, чтобы создать постоянный вычисленный столбец, используя CHECKSUM от неприятного поля поиска. У нас было поле автоматической инкреции ID и введено (контрольная сумма, id)

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

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

Удачи!