问题
I need to generate a unique code with 5 lengths with the given number. In other words, I need to encode natural number to 5 length unique code
I wanna give fixed-length rememberable code to the customer, and keep the sequential number in the database and encode or decode when needed.
The given number can be in the range of 1 to 9999999. But the result always must be 5 lengths.
for example
1 => a56er or 2 => c7gh4
Uniqueness is important I googled a lot and I can't find a solution.
回答1:
The given number can be in the range of 1 to 9999999
Right. So you need to encode 24 bits of information, and you have 5 characters in which to do that - so you need 5 bits per character. That's pleasantly in the range of "only digits and lower case ASCII characters" and you can even remove points of confusion like "o/0" and "i/1".
Note that this isn't in any way "secure" - it's entirely predictable and reversible. If you don't want customers being able to reverse engineer their sequence number from the encoded form, it won't work. But it's a simple way of encoding a number as a fixed-length string.
Sample code showing encoding and decoding:
using System;
using System.Globalization;
public class Test
{
static void Main()
{
EncodeDecode(10);
EncodeDecode(100);
EncodeDecode(1000);
EncodeDecode(10000);
EncodeDecode(100000);
EncodeDecode(1000000);
EncodeDecode(9999999);
void EncodeDecode(int number)
{
string encoded = EncodeBase32(number);
int decoded = DecodeBase32(encoded);
Console.WriteLine($"{number} => {encoded} => {decoded}");
}
}
private const string Base32Alphabet =
"23456789abcdefghjklmnpqrstuvwxyz";
private static string EncodeBase32(int number)
{
// TODO: Range validation
char[] chars = new char[5];
for (int i = 0; i < 5; i++)
{
chars[i] = Base32Alphabet[number & 0x1f];
number = number >> 5;
}
return new string(chars);
}
private static int DecodeBase32(string text)
{
if (text.Length != 5)
{
throw new ArgumentException("Invalid input: wrong length");
}
int number = 0;
for (int i = 4; i >= 0; i--)
{
number = number << 5;
int index = Base32Alphabet.IndexOf(text[i]);
if (index == -1)
{
throw new ArgumentException("Invalid input: invalid character");
}
number |= index;
}
return number;
}
}
Output:
10 => c2222 => 10
100 => 65222 => 100
1000 => az222 => 1000
10000 => jsb22 => 10000
100000 => 2p352 => 100000
1000000 => 2ljy2 => 1000000
9999999 => zm7kb => 9999999
回答2:
Based on your requirements, I will first answer to your question, then give you what I think is the best solution.
So, based on your number 1 to 9999999, you can use a SHA256 or MD5 or any other hashing function to generate a string, then use Substring on a random part of the string, to get the code you ask for.
A more simple approach which I personally used is to just ignore the user input, and use Guid.NewGuid() function, which will generate a random string of 16 characthers, on which you can remove the "-" and take 5 random charachters with substring and get the code you want.
Guid.NewGuid()
Gives you codes in a fashion like "a869ee3e-13b2-46ce-8c09-ff8998ab9393". Then you apply a
string.Replace("-")
and you get "a869ee3e13b246ce8c09ff8998ab9393" then you take a random piece of 5 charachters in the string (just do a substring and pass as starting point a Random number that is ranged between 1 and string lenght -5 (if you want a 5 lenght charachter).
Or to put more simple
Guid.NewGuid().ToString().Replace("-", "").Substring(x.Next(1,27),5)
This will give the code you're asking for
来源:https://stackoverflow.com/questions/65230541/generate-5-length-unique-code-from-natural-number