[英]Generate a short code based on a unique string in C#
我即將推出新的在線服務測試版。 Beta用戶將被發送一個唯一的“訪問代碼”,允許他們注冊該服務。
我認為我只會根據他們的電子郵件生成代碼,而不是存儲訪問代碼列表,因為這本身就是獨一無二的。
我最初的想法是將電子郵件與唯一字符串組合,然后Base64對其進行編碼。 但是,我正在尋找更短的代碼,比如長5個數字。
如果訪問代碼本身需要是唯一的,則很難確保不會發生沖突。 如果您能夠容忍兩個用戶巧合地共享相同訪問代碼的情況,那么它將變得非常容易。
如所提出的,將電子郵件地址的base-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 in email:running total + = [large prime] * [unicode value]
然后運行總計%大5位數
正如他所指出的那樣,除非你有一個很好的哈希函數,否則這不會是唯一的。 你很可能會發生碰撞。 不確定是否重要。
對我來說更容易的是,如果您已經知道有效的電子郵件,只需在注冊時查看用戶的電子郵件列表中的有效電子郵件嗎? 為什么要煩擾代碼呢?
如果你真的想要一個唯一的標識符,最簡單的方法就是使用所謂的GUID。 C#原生支持這一點 。 您可以將其存儲在Users表中。 但是,對於用戶來說,記住/輸出它的時間太長了,如果這是你想要做的事情,那么對於每個用戶來說幾乎肯定是唯一的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.