Создайте короткий код на основе уникальной строки в C#

StackOverflow https://stackoverflow.com/questions/6810144

  •  25-10-2019
  •  | 
  •  

Вопрос

Я просто собираюсь запустить бета -версию нового онлайн -сервиса. Бета -подписчики будут отправлены уникальным «кодом доступа», который позволяет им зарегистрироваться для службы.

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

Моя первоначальная мысль состояла в том, чтобы объединить электронное письмо с уникальной строкой, а затем База64 кодировать это. Тем не менее, я искал коды, которые немного короче, скажем, 5 цифр длиной.

Это было полезно?

Решение

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

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

Одним из вариантов является взятие хэша SHA-1-HMAC (System.cryptography.hmacsha1) адреса электронной почты с известным секретным ключом. Выход хэша представляет собой 20-байтовую последовательность. Затем вы могли бы усечь хэш -детерминистически. Например, в следующем, GetCodeForEmail("test@example.org") дает код «pe2weg»:

// define characters allowed in passcode.  set length so divisible into 256
static char[] ValidChars = {'2','3','4','5','6','7','8','9',
                   'A','B','C','D','E','F','G','H',
                   'J','K','L','M','N','P','Q',
                   'R','S','T','U','V','W','X','Y','Z'}; // len=32

const string hashkey = "password"; //key for HMAC function -- change!
const int codelength = 6; // lenth of passcode

string GetCodeForEmail(string address)
{
    byte[] hash;
    using (HMACSHA1 sha1 = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(hashkey)))
        hash = sha1.ComputeHash(UTF8Encoding.UTF8.GetBytes(address));
    int startpos = hash[hash.Length -1] % (hash.Length - codelength);
    StringBuilder passbuilder = new StringBuilder();
    for (int i = startpos; i < startpos + codelength; i++)
        passbuilder.Append(ValidChars[hash[i] % ValidChars.Length]);
    return passbuilder.ToString();
}

Другие советы

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

Итак, звучит так, как то, что вы хотите сделать здесь, - это создать хэш -функцию специально для электронных писем, как указал @can Poyragzoglu. Очень простой может выглядеть примерно так:

(псевдо -код) foreach char c в электронной почте: Запуск Total += [большой Prime] * [Значение Unicode

Затем выполните общее количество % большого 5 -значного числа

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

Что мне кажется проще, если вы уже знаете действительные электронные письма, просто проверьте электронную почту пользователя по вашему списку действительных при регистрации? Зачем вообще беспокоиться о коде?

Если вы действительно хотите уникальный идентификатор, самый простой способ сделать это, вероятно, просто использовать то, что называется GUID. C# Назнаноется это. Анкет Вы можете сохранить это в своем таблице пользователей. Тем не менее, для пользователя было бы слишком долго, чтобы пользователь когда -либо помнил/вводит, это почти наверняка было бы уникальным для каждого, если бы вы этого пытаетесь сделать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top