我有订单的表,我想给用户提供一个订单生成一个唯一的代码,而隐藏身份递增整数主键,因为我不想放弃多少订单已经作出。
确保代码是唯一的一个简单的方法是使用主键来确定的代码。
所以,我怎么能够把一个整成一个友好的,比如说8个字母数字代码,每个代码都是唯一的?
我有订单的表,我想给用户提供一个订单生成一个唯一的代码,而隐藏身份递增整数主键,因为我不想放弃多少订单已经作出。
确保代码是唯一的一个简单的方法是使用主键来确定的代码。
所以,我怎么能够把一个整成一个友好的,比如说8个字母数字代码,每个代码都是唯一的?
假设订单正在创建的总数不会让你的池标识符的总数附近的任何地方,一个合理有效的方法是简单地生成一个随机标识符,看看它是否已被使用; 继续下去,直到你找到一个以前未曾使用产生新的标识符。
最简单的方法(如果你想要一个字母数字代码)是整数主键转换为十六进制(如下图所示)。 而且,你可以使用`PadLeft()”,以确保串有8个字符。 但是,当订单数量增长,8个字符是不够的。
var uniqueCode = intPrimaryKey.ToString("X").PadLeft(8, '0');
或者,你可以创建你的主键的偏移,将其转换为十六进制,像之前如下:
var uniqueCode = (intPrimaryKey + 999).ToString("X").PadLeft(8, '0');
一个快速简便的方法来做到这一点是有一个有默认值的GUID列
left(newid(),8)
该解决方案通常会给你的每一行的唯一值。 但如果你有非常大量的订单,这将不会是唯一的,你应该只使用NEWID()值来生成GUID。
我只想用MD5这一点。 MD5提供了代表您的客户订单整数的一小部分足够的“唯一性”。
举一个例子看到这个答案 。 您将需要从字符串调整输入参数为int(或可选择地只是调用ToString
上你的电话号码,并使用代码按)。
如果你想的东西,这将是难以追查,你不;吨介意它是16个字符,你可以使用这样的事情,其中包括一些随机数,并与他们混合原始输入的字节位置:(编辑来让一个位更难以追踪,通过用产生的随机数-ING XOR)。
public static class OrderIdRandomizer
{
private static readonly Random _rnd = new Random();
public static string GenerateFor(int orderId)
{
var rndBytes = new byte[4];
_rnd.NextBytes(rndBytes);
var bytes = new byte[]
{
(byte)rndBytes[0],
(byte)(((byte)(orderId >> 8)) ^ rndBytes[0]),
(byte)(((byte)(orderId >> 24)) ^ rndBytes[1]),
(byte)rndBytes[1],
(byte)(((byte)(orderId >> 16)) ^ rndBytes[2]),
(byte)rndBytes[2],
(byte)(((byte)(orderId)) ^ rndBytes[3]),
(byte)rndBytes[3],
};
return string.Concat(bytes.Select(b => b.ToString("X2")));
}
public static int ReconstructFrom(string generatedId)
{
if (generatedId == null || generatedId.Length != 16)
throw new InvalidDataException("Invalid generated order id");
var bytes = new byte[8];
for (int i = 0; i < 8; i++)
bytes[i] = byte.Parse(generatedId.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
return (int)(
((bytes[2] ^ bytes[3]) << 24) |
((bytes[4] ^ bytes[5]) << 16) |
((bytes[1] ^ bytes[0]) << 8) |
((bytes[6] ^ bytes[7])));
}
}
用法:
var obfuscatedId = OrderIdRandomizer.GenerateFor(123456);
Console.WriteLine(obfuscatedId);
Console.WriteLine(OrderIdRandomizer.ReconstructFrom(obfuscatedId));
缺点:如果该算法是知道,这显然是容易折断。 优点:它是完全自定义的,即没有一个既定的算法,如MD5,可能是更容易猜测/破解如果你不知道正在使用哪种算法做。