从自然数生成 5 个长度的唯一代码
Generate 5 length unique code from natural number
我需要使用给定的数字生成一个具有 5 个长度的唯一代码。换句话说,我需要将自然数编码为 5 长度的唯一代码
我想给客户定长可记忆的代码,把序列号保存在数据库里,需要的时候编码或者解码。
给定的数字可以在1到9999999的范围内。
但结果总是必须是 5 个长度。
例如
1 => a56er
or
2 => c7gh4
独特性很重要
我在谷歌上搜索了很多,但找不到解决方案。
根据您的要求,我会先回答您的问题,然后给出我认为最好的解决方案。
因此,根据您的数字 1 到 9999999,您可以在字符串的随机部分使用 SHA256 or MD5 or any other hashing function to generate a string, then use Substring,以获得您要求的代码。
我个人使用的一种更简单的方法是忽略用户输入,并使用 Guid.NewGuid() 函数,这将生成一个 16 个字符的随机字符串,您可以删除其中的“-”和取5个带子串的随机字符,得到你想要的代码。
Guid.NewGuid()
以“a869ee3e-13b2-46ce-8c09-ff8998ab9393”之类的方式为您提供代码。然后你申请一个
string.Replace("-")
然后你得到“a869ee3e13b246ce8c09ff8998ab9393”然后你在字符串中随机取一块5个字符(只需做一个子字符串并作为起点传递一个介于1和字符串长度-5之间的随机数(如果你想要一个 5 长的字符)。
或者更简单
Guid.NewGuid().ToString().Replace("-", "").Substring(x.Next(1,27),5)
这将提供您要求的代码
The given number can be in the range of 1 to 9999999
没错。所以你需要对 24 位信息进行编码,并且你有 5 个字符可以做到这一点 - 所以每个字符需要 5 位。这在“只有数字和小写 ASCII 字符”的范围内令人愉快,你甚至可以删除像“o/0”和“i/1”这样的混淆点。
请注意,这绝不是“安全的”——它是完全可预测和可逆的。如果您不希望客户能够从编码形式逆向工程他们的序列号,那将行不通。但这是一种将数字编码为固定长度字符串的简单方法。
显示编码和解码的示例代码:
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;
}
}
输出:
10 => c2222 => 10
100 => 65222 => 100
1000 => az222 => 1000
10000 => jsb22 => 10000
100000 => 2p352 => 100000
1000000 => 2ljy2 => 1000000
9999999 => zm7kb => 9999999
我需要使用给定的数字生成一个具有 5 个长度的唯一代码。换句话说,我需要将自然数编码为 5 长度的唯一代码
我想给客户定长可记忆的代码,把序列号保存在数据库里,需要的时候编码或者解码。
给定的数字可以在1到9999999的范围内。 但结果总是必须是 5 个长度。
例如
1 => a56er or 2 => c7gh4
独特性很重要 我在谷歌上搜索了很多,但找不到解决方案。
根据您的要求,我会先回答您的问题,然后给出我认为最好的解决方案。
因此,根据您的数字 1 到 9999999,您可以在字符串的随机部分使用 SHA256 or MD5 or any other hashing function to generate a string, then use Substring,以获得您要求的代码。
我个人使用的一种更简单的方法是忽略用户输入,并使用 Guid.NewGuid() 函数,这将生成一个 16 个字符的随机字符串,您可以删除其中的“-”和取5个带子串的随机字符,得到你想要的代码。
Guid.NewGuid()
以“a869ee3e-13b2-46ce-8c09-ff8998ab9393”之类的方式为您提供代码。然后你申请一个
string.Replace("-")
然后你得到“a869ee3e13b246ce8c09ff8998ab9393”然后你在字符串中随机取一块5个字符(只需做一个子字符串并作为起点传递一个介于1和字符串长度-5之间的随机数(如果你想要一个 5 长的字符)。
或者更简单
Guid.NewGuid().ToString().Replace("-", "").Substring(x.Next(1,27),5)
这将提供您要求的代码
The given number can be in the range of 1 to 9999999
没错。所以你需要对 24 位信息进行编码,并且你有 5 个字符可以做到这一点 - 所以每个字符需要 5 位。这在“只有数字和小写 ASCII 字符”的范围内令人愉快,你甚至可以删除像“o/0”和“i/1”这样的混淆点。
请注意,这绝不是“安全的”——它是完全可预测和可逆的。如果您不希望客户能够从编码形式逆向工程他们的序列号,那将行不通。但这是一种将数字编码为固定长度字符串的简单方法。
显示编码和解码的示例代码:
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;
}
}
输出:
10 => c2222 => 10
100 => 65222 => 100
1000 => az222 => 1000
10000 => jsb22 => 10000
100000 => 2p352 => 100000
1000000 => 2ljy2 => 1000000
9999999 => zm7kb => 9999999