Преобразуйте строку классификации из десяти символов в четыре символа один в C # - PullRequest
0 голосов
/ 28 мая 2010
  1. Какой лучший способ преобразовать (в хеш) строку, например 3800290030, которая представляет идентификатор для классификации в четырехсимвольную, такую ​​как 3450 (мне нужно поддерживать максимум 9999 классов). У нас будет только менее 1000 классов в 10-символьном пространстве, и оно никогда не увеличится до более чем 10 тыс.
  2. Хеш должен быть уникальным и всегда одинаковым для одного и того же входа.
  3. Полученная строка должна быть числовой (но она будет сохранена как char (4) в SQL Server).

Я снял требование об обратимости.

Это мое решение, пожалуйста, прокомментируйте:

        string classTIC = "3254002092";
        MD5 md5Hasher = MD5.Create();

        byte[] classHash = md5Hasher.ComputeHash(Encoding.Default.GetBytes(classTIC));
        StringBuilder sBuilder = new StringBuilder();

        foreach (byte b in classHash)
        {
            sBuilder.Append(b.ToString());
        }

        string newClass = (double.Parse(sBuilder.ToString())%9999 + 1).ToString();

Ответы [ 8 ]

2 голосов
/ 28 мая 2010

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

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

Эта короткая версия может быть просто увеличена на единицу с каждым новым идентификатором.

2 голосов
/ 28 мая 2010
  1. Вы можете сделать что-то вроде

    str.GetHashCode ()% 9999 + 1;

  2. Хеш не может быть уникальным, поскольку у вас более 9 999 строк

  3. Он не уникален, поэтому он не может быть обратимым

и, конечно, мой ответ неверен, если у вас не более 9999 различных классов по 10 символов.

В случае, если у вас не более 9999 классов, вам необходимо сопоставить строковый идентификатор с его 4-символьным представлением - например, сохранить строки в списке, и каждый ключ строки будет его индексом в списке

1 голос
/ 28 мая 2010

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

Вам нужно создать таблицу постоянных сопоставлений для преобразования строки в число. Логически похоже на Dictionary<string, int>. Первая строка, которую вы добавите, получает номер 0. Когда вам нужно отобразить, найдите строку и верните ее ассоциированный номер. Если его нет, добавьте строку и просто присвойте ей номер, равный количеству.

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

1 голос
/ 28 мая 2010
  1. да не знаю
  2. Уникальный сложно, у вас есть - по вашему запросу - 4 символа - это максимум 9999, столкновение произойдет.
  3. Хэш необратим. Данные потеряны (очевидно).
0 голосов
/ 28 мая 2010

используйте md5 или sha как:

string = substring(md5("05910395410"),0,4)

или напишите свой собственный простой метод, например

sum = 0
foreach(char c in string)
{
  sum+=(int)c;
}
sum %= 9999
0 голосов
/ 28 мая 2010

Преобразуйте ваш int в двоичный файл, а затем base64 закодируйте его. Тогда это не будут числа, но это будет обратимый хеш.

Edit:

Насколько мне известно, ты просишь невозможного.

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

Во-вторых, из-за вышеизложенного также невозможно сделать его обратимым. Таким образом, об этом не может быть и речи.

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

0 голосов
/ 28 мая 2010

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

0 голосов
/ 28 мая 2010

Преобразование числа в base35 / bas e36

например: 3800290030 десятичный = 22CGHK5 base-35 // длина: 7

Или может быть преобразован в Base60 [игнорируя прописные O и маленькие o, чтобы не путать с 0]

например: 3800290030 десятичное = 4tDw7A base-60 // длина: 6

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