我想创建一个在表格中唯一但不增量的PIN,以使人们难以猜测。 理想情况下,我希望能够在SQL Server中创建这个,但如果需要,我可以通过ASP.Net来完成。为表格的每条记录创建一个唯一的标识(PIN)
编辑
很抱歉,如果我没说清楚:我不是在寻找一个GUID所有我需要的是该表的唯一ID;我只是不希望它是增量式的。
我想创建一个在表格中唯一但不增量的PIN,以使人们难以猜测。 理想情况下,我希望能够在SQL Server中创建这个,但如果需要,我可以通过ASP.Net来完成。为表格的每条记录创建一个唯一的标识(PIN)
编辑
很抱歉,如果我没说清楚:我不是在寻找一个GUID所有我需要的是该表的唯一ID;我只是不希望它是增量式的。
将uniqueidentifier列添加到您的表中,默认值为NEWID()。这将确保每列获得一个新的唯一标识符,这不是增量式的。
CREATE TABLE MyTable (
...
PIN uniqueidentifier NOT NULL DEFAULT newid()
...
)
uniqueidentifier保证是唯一的,不仅适用于此表,而且适用于所有表格。
如果这是你的应用程序太大,你可以得到你从这个数字更小的PIN码,你可以做到这一点,如:
SELECT RIGHT(REPLACE((SELECT PIN from MyTable WHERE UserID=...), '-', ''), 4/*PinLength*/)
注意,返回小PIN码不能保证所有用户的独特,但可能更易于管理,具体取决于您的应用程序。
编辑:如果你想要一个小的PIN码,保证唯一性,棘手的部分是,你需要知道至少最大的用户数量,以便选择适当的大小的引脚。随着用户数量的增加,PIN冲突的可能性增加。这与Coupon Collector's问题类似,并且接近nlogn复杂度,这会导致非常慢的插入(插入时间与现有元素的数量成比例,因此插入M个项目然后变为O(N^2))。避免这种情况最简单的方法是使用大的唯一ID,并且只选择其中一部分用于PIN,假设您可以放弃PIN值的唯一性。
EDIT2:
如果你有这样的
CREATE TABLE YourTable (
[id] [int] IDENTITY(1,1) NOT NULL,
[pin] AS (CONVERT(varchar(9),id,0)+RIGHT(pinseed,3)) PERSISTED,
[pinseed] [uniqueidentifier] NOT NULL
)
此表定义将创建从pinseed
一个唯一的ID和行ID的pin
。 (RAND不起作用 - 因为SQL服务器将使用相同的值来初始化多行,NEWID并非如此)
就这样说,我建议你不要考虑这个方式安全。您应该认为其他用户总是可以猜测其他人的PIN,除非您以某种方式限制允许的猜测次数(例如,在3次尝试后停止接受请求,类似于在3次错误的PIN输入之后银行对您的银行卡进行绑定。)
怎么样具有缺省值NEWID()的UNIQUEIDENTIFIER类型列?
这将为每一行生成一个新的GUID。
再次我不需要一个GUID - 请参阅@smdrager – Josh 2010-07-26 16:36:21
请记住,通过要求唯一的PIN码(这是不常见的),您将限制允许的最大用户数到PIN规范。你确定你想要吗?
一个不是很优雅的解决方案,但它的工作原理是使用UNIQUE字段,然后循环尝试插入随机生成的PIN,直到插入成功。
您可以使用以下命令来生成BIGINT或其他数据类型。
SELECT CAST(ABS(CHECKSUM(NEWID()))%2000000000+1 as BIGINT) as [PIN]
这产生了1到20亿的数字。您将模拟某种程度的随机性,因为它来自NEWID函数。您也可以根据需要格式化结果。
这并不能保证唯一性。我建议你在PIN列上使用唯一的约束。而且,创建新PIN的代码应该在分配值之前检查新值是否是唯一的。
使用随机数字。
SET @uid = ROUND(RAND()* 100000)
更稀疏的值是在表中,更好的工作的。如果分配值的数量变大与可用值的数量有关系,那么它就不能正常工作。
一旦生成号码,您有几个选项。 1)在重试循环内插入值。如果您遇到重复错误,请重新生成该值(或尝试值+/- 1)并重试。 2)生成值并查找MAX和MIN现有唯一标识符。
DECLARE
@uid INTEGER
SET @uid = ROUND(RAND() * 10000, 1)
SELECT @uid
SELECT MAX(uid) FROM table1 WHERE uid < @uid
SELECT MIN(uid) FROM table1 WHERE uid > @uid
如果已经分配了随机值,则MIN和MAX值将为您提供一系列可用的值。
OP想要“在表格中独一无二的PIN”......您的实施起初可能会感觉正确,但碰撞接近50%的机会少于2500行。有关更多信息,请参见http://en.wikipedia.org/wiki/Birthday_problem。 – 2014-09-19 14:47:04
有多少位数?数字或字母数字?当然,所有与安全通信初始PIN码有关的问题。 – 2010-07-26 16:38:14
理想情况下尽可能短 - 可以是以太数字或字母数字。 – Josh 2010-07-26 17:10:42