c# - C#中根据唯一字符串生成短代码

标签 c# .net serial-number

我即将推出一项新的在线服务的测试版。 Beta 订阅者将收到一个唯一的“访问代码”,允许他们注册该服务。

与其存储访问代码列表,不如根据他们的电子邮件生成一个代码,因为这本身是独一无二的。

我最初的想法是将电子邮件与一个唯一的字符串结合起来,然后是 Base64对其进行编码。但是,我一直在寻找更短的代码,比如 5 位数字。

最佳答案

如果访问码本身需要唯一,就很难保证不会发生碰撞。如果您可以容忍两个用户可能巧合地共享相同访问代码的情况,事情就会变得容易得多。

如建议的那样,采用电子邮件地址的 base-64 编码与已知字符串连接,可能会引入安全漏洞。如果您使用与已知单词连接的电子邮件地址的 base64 输出,用户只需取消对访问代码的编码并推导出用于生成代码的算法。

一种选择是使用已知 key 获取电子邮件地址的 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();
}

关于c# - C#中根据唯一字符串生成短代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6810144/

相关文章:

c# - 如何使用 FluentAssertions 控制字典成员的 "Equality"

c# - 在回传之间存储 GridViewRow 对象

c# - IReadOnlyCollection 与 ReadOnlyCollection

linux - 不使用 sudo 提取 Linux 序列号

c# - 如何删除所有匹配和删除文本

C#调用Listview的SelectedIndexChange事件中的文本框焦点失去对事件完成的关注

c# - Dropbox API "USER TOKEN", "USER SECRET"

c# - 序列不包含元素

electron - 是否可以为我的 Electron 应用程序创建产品 key ?

delphi - 如何在Delphi中获取主板ID或序列号?