Java论坛网»Java技术»要生成批量电话充值卡密码, 跪求唯一值算法!
要生成批量电话充值卡密码, 跪求唯一值算法!
问?:
生成量大概有几百万, 15位十进制卡密码, 要求密码不能重复.
答!: 1:
直接用随机函数生成就是了,每生成一个就往数据库里插,而数据库里把这个密码字段设成主键,插进去就算,插不进(重复了)就扔了。
只是记得每一次调整一点算法的细节或随机种子,免得让别人从一个密码自己推导出一大堆来。
只是记得每一次调整一点算法的细节或随机种子,免得让别人从一个密码自己推导出一大堆来。
答!: 2:
你不要做违法的事,呵呵
答!: 3:
最佳算法。举例为5位密码,生成100个
那么生成的密码为
00000+(0~999的随机数)
01000+(0~999的随机数)
02000+(0~999的随机数)
...
99000+(0~999的随机数)
共计100个
如果还想弄得更混乱一些,那么就重排每个密码的各个位.....
那么生成的密码为
00000+(0~999的随机数)
01000+(0~999的随机数)
02000+(0~999的随机数)
...
99000+(0~999的随机数)
共计100个
如果还想弄得更混乱一些,那么就重排每个密码的各个位.....
答!: 4:
用随机数吧,rand
答!: 5:
各位还没有明白我的意思.
生成的密码一个是要唯一, 再就是要随机, 这是要做为密码的, 不是做GUID.
SQL Server里面有一个NewID()函数, 就是那样的功能. 不过它生成的数太长了, 我只要15位.
生成的密码一个是要唯一, 再就是要随机, 这是要做为密码的, 不是做GUID.
SQL Server里面有一个NewID()函数, 就是那样的功能. 不过它生成的数太长了, 我只要15位.
答!: 6:
你只管随机就行了,“唯一性”的任务让数据库帮你搞定,只要你把它设为主健。
数据库系统既然已经有了防止数据重复插入的好方法,可用的时候,何必重复发明轮子呢?:P。
数据库系统既然已经有了防止数据重复插入的好方法,可用的时候,何必重复发明轮子呢?:P。
答!: 7:
对了,你几百万的数据量,应该不会不用数据库吧?
答!: 8:
如果那样的话就用java的Set类来帮你防止重复插入。
答!: 9:
是要把生成的密码放入数据表, 用主键或者唯一约速我还没试过. 可以试下,但我还是有点怀疑,就算是索引,几百万还是有压力的吧?
Set这种东西要先读入吧? 读几百万的数据, 我看机器也差不多了...
Set这种东西要先读入吧? 读几百万的数据, 我看机器也差不多了...
答!: 10:
在点压力就有点吧。
这种事又不是天天做。
总不至于你们公司每天都能卖出好几百万张卡吧。:$
这种事又不是天天做。
总不至于你们公司每天都能卖出好几百万张卡吧。:$
答!: 11:
不会每天出, 但也要和之前的相比较吧?
答!: 12:
那是的。
不过你越说反而让我越感觉到了使用数据库的好处,呵呵。
不过你越说反而让我越感觉到了使用数据库的好处,呵呵。
答!: 13:
比如可以很方便地跟之前的比较。
答!: 14:
但是如果要一批生成几十万的话,每个都去数据表查一次,太恐怖了.
答!: 15:
不用查啊,直接往里插,成功就成功,失败就扔掉。
答!: 16:
当然,数据库自己还是要查一下的,否则它怎么实行约束呢?但就不要管那么多了嘛,它总有办法优化的,比如索引一下。而且总比你两次执行SQL语句效率高啊。
答!: 17:
我们头说,做唯一约束的效果也不理想.
答!: 18:
那,那就在内存里先用Set搞定再一次性插入吧,也不过几十兆内存。-_-。
但这样跟以前的比较怎么办啊?
要不让15位的前面几位包含日期信息,这样不是同一天产生的绝对不会重复,不过最好变换一下,让人一下子看出来就没意思了。
但这样跟以前的比较怎么办啊?
要不让15位的前面几位包含日期信息,这样不是同一天产生的绝对不会重复,不过最好变换一下,让人一下子看出来就没意思了。
答!: 19:
如果每一张都有有效期就好了,每过一段时间就可以删掉或重用一些。这样对以前的重复比较压力就小了。
不过我只是觉得贵公司的业务量有那么大吗?100万张卡,每张赚10块,1000万就有了。
不过我只是觉得贵公司的业务量有那么大吗?100万张卡,每张赚10块,1000万就有了。
答!: 20:
没有老板也要我做几千万张卡的准备啊! T_T
答!: 21:
我觉得可以考虑优化一下,用多个表存,每个表100万个,有助于提高效率。
然后当给定一个密吗,用可以用表名做索引查寻。比如让15位的前几位跟表名的后缀相同。
然后当给定一个密吗,用可以用表名做索引查寻。比如让15位的前几位跟表名的后缀相同。
答!: 22:
看来你没看懂我的算法....可怜的孩子
答!: 23:
楼主公司是给移动做冲值卡的?
答!: 24:
开始没仔细看,timerri()朋友给的方法的确巧妙。
建议楼主在15位中留出9位作序列号,其它6位用随机数,这样将来能扩充到10亿,全中国差不多每3个人中可以有2个是你们的客户了,呵呵。要是再不够就再说吧。让这10亿的业务量先把公司的收入冲上去再说。
问题解决了,结帖吧。
建议楼主在15位中留出9位作序列号,其它6位用随机数,这样将来能扩充到10亿,全中国差不多每3个人中可以有2个是你们的客户了,呵呵。要是再不够就再说吧。让这10亿的业务量先把公司的收入冲上去再说。
问题解决了,结帖吧。
答!: 25:
一定要计算一下概率,如果留出位数太少,会被猜出来的。
比如说在六位随机数(999999)里面只产生100个号码就可以了。
答!: 26:
支持steedhorse(晨星)...简单结了.
答!: 27:
支持timerri()推荐的算法
答!: 28:
//一定要计算一下概率,如果留出位数太少,会被猜出来的。
——这个好解决,大不了用18位的密码,嘿嘿。
——这个好解决,大不了用18位的密码,嘿嘿。
答!: 29:
“如果还想弄得更混乱一些,那么就重排每个密码的各个位.....”
重排的话好像会重复掉哦
加上有效期限应该就很难猜出来了
重排的话好像会重复掉哦
加上有效期限应该就很难猜出来了
答!: 30:
不如先插到数据库再去掉重复的.
答!: 31:
把分给我吧。看看我的方法。
首先,建立个数据库
CREATE TABLE [dbo].[Card] (
[ID] [int] IDENTITY (1, 1) NOT NULL ,
[CardID] [nvarchar] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[CardPass] [nvarchar] (15) COLLATE Chinese_PRC_CI_AS NOT NULL
) ON [PRIMARY]
GO
记得,ID,卡号和密码都要设置为主键,为了防止重复。如果最后为了查看结果是不是生成的数量正确,最好把ID加上自动增量
然后在查询分析器里输入语句,之所以在查询分析器里是为了防止超时。呵呵~~
-- 程序名称:生成指定位数的不重复的卡号和密码 --
-- 作 者:阳光蛐蛐 --
-- E - Mail:jessicor001@163.com --
-- 修改时间:2006年7月30日--
DECLARE @CardPass bigINT--生成卡号密码
DECLARE @CardID bigINT --生成卡号
declare @i int
set @i=1
while @i<50000--生成50000
begin
set @CardPass=convert(decimal(8),RAND()*100000000)--这儿是重点,要修改位数和后面的0哦
set @CardID=convert(decimal(12),RAND()*1000000000000)--这儿是重点,要修改位数和后面的0哦
if len(@CardPass)<8
begin
set @CardPass=convert(decimal(8),(convert(varchar(8),@CardPass)+REPLICATE('0',8-len(@CardPass))))
end
if len(@CardID)<12
begin
set @CardID=convert(decimal(12),(convert(varchar(12),@CardID)+REPLICATE('0',12-len(@CardID))))
end
INSERT INTO Card
(CardPass, CardID)
VALUES (@CardPass,@CardID)
set @i=@i+1
end
用SQLserver查询分析器20万生成起来不到2分钟,很快的。如果用程序就不止这样了。呵呵,试试吧。不过,可行的话,一定要甩分给我哦
首先,建立个数据库
CREATE TABLE [dbo].[Card] (
[ID] [int] IDENTITY (1, 1) NOT NULL ,
[CardID] [nvarchar] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[CardPass] [nvarchar] (15) COLLATE Chinese_PRC_CI_AS NOT NULL
) ON [PRIMARY]
GO
记得,ID,卡号和密码都要设置为主键,为了防止重复。如果最后为了查看结果是不是生成的数量正确,最好把ID加上自动增量
然后在查询分析器里输入语句,之所以在查询分析器里是为了防止超时。呵呵~~
-- 程序名称:生成指定位数的不重复的卡号和密码 --
-- 作 者:阳光蛐蛐 --
-- E - Mail:jessicor001@163.com --
-- 修改时间:2006年7月30日--
DECLARE @CardPass bigINT--生成卡号密码
DECLARE @CardID bigINT --生成卡号
declare @i int
set @i=1
while @i<50000--生成50000
begin
set @CardPass=convert(decimal(8),RAND()*100000000)--这儿是重点,要修改位数和后面的0哦
set @CardID=convert(decimal(12),RAND()*1000000000000)--这儿是重点,要修改位数和后面的0哦
if len(@CardPass)<8
begin
set @CardPass=convert(decimal(8),(convert(varchar(8),@CardPass)+REPLICATE('0',8-len(@CardPass))))
end
if len(@CardID)<12
begin
set @CardID=convert(decimal(12),(convert(varchar(12),@CardID)+REPLICATE('0',12-len(@CardID))))
end
INSERT INTO Card
(CardPass, CardID)
VALUES (@CardPass,@CardID)
set @i=@i+1
end
用SQLserver查询分析器20万生成起来不到2分钟,很快的。如果用程序就不止这样了。呵呵,试试吧。不过,可行的话,一定要甩分给我哦
答!: 32:
1.密码表中建主键是必要的,如果表中没有唯一性约束,程序就必须做缓存检查重复ID
2.生成15位密码插入数据库表
随机密码完全算法,最大量为10的15次方:
import java.util.Random;
class PasswordRandom {
public static void main(String[] args)
{
Random random = new Random();
StringBuffer password = new StringBuffer();
for(int i=0; i<15; i++) {
password.append(random.nextInt(10));
}
System.out.println(password.toString());
}
}
3.如果为了进一步提高安全性,执行此步骤,序列号与已经生成好的随机密码做随机映射,必要性不太大,只是为了给每个序列号分配一个密码,分配方法有多种,也可以在生成密码的时候直接映射。
4.不管采用什么方法,切记:
a.密码不可有顺序性
b.生成密码总量:可产生最大量 比例降到最小,如1:99999999999
c.密码不可含有与序列号相关的任何信息,加上序列号更是多余之极
d.序列号与密码建立随机映射,结果即是你想要的成果。
2.生成15位密码插入数据库表
随机密码完全算法,最大量为10的15次方:
import java.util.Random;
class PasswordRandom {
public static void main(String[] args)
{
Random random = new Random();
StringBuffer password = new StringBuffer();
for(int i=0; i<15; i++) {
password.append(random.nextInt(10));
}
System.out.println(password.toString());
}
}
3.如果为了进一步提高安全性,执行此步骤,序列号与已经生成好的随机密码做随机映射,必要性不太大,只是为了给每个序列号分配一个密码,分配方法有多种,也可以在生成密码的时候直接映射。
4.不管采用什么方法,切记:
a.密码不可有顺序性
b.生成密码总量:可产生最大量 比例降到最小,如1:99999999999
c.密码不可含有与序列号相关的任何信息,加上序列号更是多余之极
d.序列号与密码建立随机映射,结果即是你想要的成果。
答!: 33:
skystar99047(天星)
说得正是。
说得正是。
答!: 34:
楼主啊,俺不要分,只要你做好后弄几个密码给俺就行
答!: 35:
简单,安全就是美
答!: 36:
我同意楼上的楼上。
答!: 37:
easy
用过com生成GUID的工具吧,
好像有相应的API可以生成GUID,这个工具就是调用这个API的,具体哪个没研究过!
用过com生成GUID的工具吧,
好像有相应的API可以生成GUID,这个工具就是调用这个API的,具体哪个没研究过!
答!: 38:
这应该是一个数学问题,我们可以根据系统的一些数据经过某一个函数后生成密码,当然最好这个算法是不可逆的,这样不就行了,找一个学数学的问问吧,这是一个算法的问题。
答!: 39:
楼主我告诉你如何做,不过你要把卡号和密码告诉我哦嘿嘿
答!: 40:
大家没有没玩过扑克的吧,扑克需要洗牌,记得吗?
一个简单的方法就是不要在赋予用户的时候临时麻烦(随机,唯一键验证)
而是把麻烦的工作提前到整个系统投入使用前的初始化阶段
也就是说
首先执行造牌方法,生成一个从N开始到N+1千万的15位的数字表,除数字之外,再加一个是否占用的标志字段。
然后执行洗牌方法,将数字打乱,这个过程可以任意发挥,只要达到顺序越乱越好的目的。
这样,准备工作就结束了。
使用时,给用户分配密码,可以依次取第一个占用标志位为非占用的直接分配就行了,然后把占用标志改写为已占用。
这种方式,特点就是使用的时候速度是最快的,把额外需要花费的时间都提前到使用前的初始化准备工作中了。
一个简单的方法就是不要在赋予用户的时候临时麻烦(随机,唯一键验证)
而是把麻烦的工作提前到整个系统投入使用前的初始化阶段
也就是说
首先执行造牌方法,生成一个从N开始到N+1千万的15位的数字表,除数字之外,再加一个是否占用的标志字段。
然后执行洗牌方法,将数字打乱,这个过程可以任意发挥,只要达到顺序越乱越好的目的。
这样,准备工作就结束了。
使用时,给用户分配密码,可以依次取第一个占用标志位为非占用的直接分配就行了,然后把占用标志改写为已占用。
这种方式,特点就是使用的时候速度是最快的,把额外需要花费的时间都提前到使用前的初始化准备工作中了。
答!: 41:
从N开始到N+1千万 也可以改为从N开始到N+1亿,步长本身就可以是一个范围内的随机数,这样能更好地增加随机性,而不是千篇一律以1或几的固定步长增加。
答!: 42:
楼主,没那么简单的,关键是总得有办法解决重复问题。
答!: 43:
推荐在内存中生成。
理由:
1. 程序使用频率小,并非常驻核心服务程序,估计十天半月能用上一次就很不错了。
单次运行的开销即使大点也是能够接受的,
2.数据才几百万,也就是以M为单位。如果采用合理的数据结构,也不过15M左右的数据量。
即使夸张一点,乘以一个修正系数,1000%也不过 150M,在普通的pc上跑也没有问题。
如果你的程序在服务器上跑,那就更不用担心了,服务器都是以g为单位的。
即使需求增长到几千万,最大也不过是 1.5g而已,
3.用数据库存储涉及i/o,其速度无法和内存的比较,相差至少3个数量级。
4.数据库判断主键重复主要是用冗余技术--索引技术。最快的是bitmap索引。
但它适合于小数据量,且适用于查询,不适用于更新,对于几百万这种中小型的级别,不适用。
hash索引技术就比较适合于高效查询和更新了。采用内存实现hash比数据库实现的要高效,
减少了不必要的开销,至少插入数据时不用更新索引到硬盘。
还有数据库的锁机制等开销等。
5.冲突的概率:10M/power(10,15) 约等于 power(2,20) /power(2,14*3) ==1/power(2,22)
大约几百万分之一,也就是说选择15为长度,生成1千万个重复的,随机的序列,
最后一个可能冲突的概率最大,大约是几百万分之一,这可以接受。
6.java的容器的有效长度(最大元素数)是 2的31方,够用了。
具体实现很简单。
技术上:
单线程+hashmap (单处理器)
或者 多线程+hashtable (多处理器)
如果感觉默认的hashcode方法性能不好的话,可以根据需要重写。
随机数的产生很耗时的,根据不同的随机过程理论不同而不同。
如果你不能忍受。这里提供一点想法。
将目标序列均匀的分割成几个子系列,如n1,n2,n3
然后把目标系列的位数随机的的分配给子系列。
每一个子系列采用确定性的复杂点的算法产生,然后重组成目标系列。
如果对子系列的算法抗破解强度不放心,可以采用每产生n次目标系列,
重新分割一次子系列。
不过我个人觉得java用这种方法也没有什么优势。
理由:
1. 程序使用频率小,并非常驻核心服务程序,估计十天半月能用上一次就很不错了。
单次运行的开销即使大点也是能够接受的,
2.数据才几百万,也就是以M为单位。如果采用合理的数据结构,也不过15M左右的数据量。
即使夸张一点,乘以一个修正系数,1000%也不过 150M,在普通的pc上跑也没有问题。
如果你的程序在服务器上跑,那就更不用担心了,服务器都是以g为单位的。
即使需求增长到几千万,最大也不过是 1.5g而已,
3.用数据库存储涉及i/o,其速度无法和内存的比较,相差至少3个数量级。
4.数据库判断主键重复主要是用冗余技术--索引技术。最快的是bitmap索引。
但它适合于小数据量,且适用于查询,不适用于更新,对于几百万这种中小型的级别,不适用。
hash索引技术就比较适合于高效查询和更新了。采用内存实现hash比数据库实现的要高效,
减少了不必要的开销,至少插入数据时不用更新索引到硬盘。
还有数据库的锁机制等开销等。
5.冲突的概率:10M/power(10,15) 约等于 power(2,20) /power(2,14*3) ==1/power(2,22)
大约几百万分之一,也就是说选择15为长度,生成1千万个重复的,随机的序列,
最后一个可能冲突的概率最大,大约是几百万分之一,这可以接受。
6.java的容器的有效长度(最大元素数)是 2的31方,够用了。
具体实现很简单。
技术上:
单线程+hashmap (单处理器)
或者 多线程+hashtable (多处理器)
如果感觉默认的hashcode方法性能不好的话,可以根据需要重写。
随机数的产生很耗时的,根据不同的随机过程理论不同而不同。
如果你不能忍受。这里提供一点想法。
将目标序列均匀的分割成几个子系列,如n1,n2,n3
然后把目标系列的位数随机的的分配给子系列。
每一个子系列采用确定性的复杂点的算法产生,然后重组成目标系列。
如果对子系列的算法抗破解强度不放心,可以采用每产生n次目标系列,
重新分割一次子系列。
不过我个人觉得java用这种方法也没有什么优势。
答!: 44:
需要那么复杂吗?
8位流水号,7位随机数
加点限制就没人猜得出来了吧?
8位流水号,7位随机数
加点限制就没人猜得出来了吧?
答!: 45:
楼主,俺有绝妙好办法,加俺QQ,654658281,俺告诉你了你给俺弄几个卡号就行,好吗?
答!: 46:
嘿嘿,本技术对这个问题是一分钟之内搞定,这样你们头儿满意不?
答!: 47:
需要那么复杂吗?
8位流水号,7位随机数
加点限制就没人猜得出来了吧?
---
前8位是流水号
随便起个密码,比如ABCD就成,和流水号串起来然后MD5,从结果里取7位出来,正取倒取从中间取随便你
除非密码和算法同时泄漏,永远出不了事
8位流水号,7位随机数
加点限制就没人猜得出来了吧?
---
前8位是流水号
随便起个密码,比如ABCD就成,和流水号串起来然后MD5,从结果里取7位出来,正取倒取从中间取随便你
除非密码和算法同时泄漏,永远出不了事
答!: 48:
机器要是快了,半分钟不到就出来了,
不过有个小小要求,此技术要保密
不过有个小小要求,此技术要保密
答!: 49:
本问题的技术瓶颈出在大家都认可都在使用的一个地方
答!: 50:
改成“本问题的技术瓶颈出在绝大多数人都认可都在使用的一个地方”。
不过呢,太极语言之父发现了,呵呵,
不过呢,太极语言之父发现了,呵呵,
答!: 51:
楼主说的好玄乎... 于是越想知道...
答!: 52:
支持有保留位的算法
例如:111110000000000
1作为保留位,0作为随机位
或者分段:000111000222000
1,2作为保留位,0作为随机位
例如:111110000000000
1作为保留位,0作为随机位
或者分段:000111000222000
1,2作为保留位,0作为随机位
答!: 53:
这个的瓶颈貌似不在算法,而是db的存储、查找,能不能把15位密码分成2部分(夸张点可以分成N份),然后建立一个连接映射表随机组合,分治思想,没仔细考虑过,这样无论密码位数无关,扩展还是可以的,每个表的数据少了一半,查找什么的也快很多 。
答!: 54:
嘿,最关键的还不是这个……
答!: 55:
不过这个也挺关键的
答!: 56:
楼主啊,几百万里俺就想要几个,行吗?
答!: 57:
呃 再次关注... 好奇...
顺便提醒楼上 30楼要省着用 要不很快就完了...
顺便提醒楼上 30楼要省着用 要不很快就完了...
答!: 58:
都什么跟什么啊
电话卡序列号最好的办法不是你插入到数据库里,而是生成一个加密的字串,冲值时去解密
你要库里存个几百万的数据,每次去检索那还不累死你的机器啊?
电话卡序列号最好的办法不是你插入到数据库里,而是生成一个加密的字串,冲值时去解密
你要库里存个几百万的数据,每次去检索那还不累死你的机器啊?
答!: 59:
路过,很有意思~~~~
答!: 60:
J2EE群7715552预留一定位置等待JAVA高手的加入!
答!: 61:
【上海腾舟卖场】为回报新老客户,笔记本配件限量大特卖,欢迎来电咨询:021-34240201
★ IT市场鱼龙混杂,产品质量层次不齐, 网络购物更要注意 , 腾舟大卖场 在易趣已经经营了7年,是老字号的视信誉为生命的大型网络超市,在 徐家汇 中心商圈,在全国几大城市,全球数个国家都有办事处,绝不会出现要保修的时候人走楼空的情况 请相信腾舟的信誉,三十余名高素质的腾舟员工将竭诚为您服务 。
★我们出售的东东每个都是 全新产品!!!
笔记本配件:笔记本 内存. 硬盘,光驱,电源,电池,键盘,笔记本包。
商品链接地址:
http://stores.ebay.com.cn/shanghaiship
上海客户可直接到徐家汇太平洋一期6楼F-1看货。电话:021-34240201 34240385
联系人:徐小姐 QQ:376882018
★MSN: mailto:xiao8yao4_xu@hotmail.com
SONY、IBM、DELL、HP上海笔记本潮流推广中。。。。。。。。
★ IT市场鱼龙混杂,产品质量层次不齐, 网络购物更要注意 , 腾舟大卖场 在易趣已经经营了7年,是老字号的视信誉为生命的大型网络超市,在 徐家汇 中心商圈,在全国几大城市,全球数个国家都有办事处,绝不会出现要保修的时候人走楼空的情况 请相信腾舟的信誉,三十余名高素质的腾舟员工将竭诚为您服务 。
★我们出售的东东每个都是 全新产品!!!
笔记本配件:笔记本 内存. 硬盘,光驱,电源,电池,键盘,笔记本包。
商品链接地址:
http://stores.ebay.com.cn/shanghaiship
上海客户可直接到徐家汇太平洋一期6楼F-1看货。电话:021-34240201 34240385
联系人:徐小姐 QQ:376882018
★MSN: mailto:xiao8yao4_xu@hotmail.com
SONY、IBM、DELL、HP上海笔记本潮流推广中。。。。。。。。
答!: 62:
sdav(ASP.net学习中)的做法安全性有问题
答!: 63:
GUID 吧..
sql server : select newID
sql server : select newID
答!: 64:
select replace(newid,'-','')
答!: 65:
其实这个问题不难。只要让15个十进制数字里面包含时间信息,就可以确保唯一了。
可以这么设计,构成这个序号的原始数据有三组:
15个10进制数可表示的数字,相当于6-7个字节可表示的数字信息。
1。以秒/或分为单位的时间信息
如果你想一次性把几千万号码都生成出来,可以使用毫秒。该值为从系统启动开始至今的毫秒数。
如过你想根据业务发展,每天或每周生成几十万,那么你可以以小时为单位。该值为2006年1月1日至今的小时数。
这个时间信息,2个字节(16位)就够了。
2。随机数
也是一个随机数,我们让随机数的域很大,但是值比较少,因此留随机数4个字节(32位)。
3。网卡MAC信息
随机取网卡MAC的某几位组成第二个不确定因素,6个字节就够了。
然后组合这3个部分。当然不应该以字节为单位,不然太容易看出规律了。因此我们以位为单位:
首先是将时间信息和随机数穿插,这个穿插的规矩是你自己定义的。为了描述方便,我们以T代表时间的位,R代表随机数的位。T2表示时间16位中的第2位,R0表示32位随机数中的第0位。
那么我们可以这样安排第一个字节:
T4 R8 T3 R7 R3 R10 R6 T2
这样第一个字节是由时间信息和随机数信息穿插而成。任何一个信息的变化都可能导致这个字节的变化,因此很难看出规律。每个字节皆是如此,直到把T0 - T15, R0 - R31都排满6个字节。这6个字节是变化多端但是却无法重复。当然,我们把这6个字节转化成10进制数,就是15个左右的数字了。可以直接用了。
但是为了再提高复杂度,导致即使知道哪些位代表什么意思依旧无法猜测出规律,那么用从网卡中提取的6个字节作为掩码,对刚刚得到的那6个进行XOR异或运算。这样彻底打破时间的递增的规律,使得到的数字更无重复的可能。
重申一下这么算得意义:
1、引入时间的好处,是将号码分段,每次判断重复的时候,只需要判断这个时间值不变的范围内的号码是否重复,而不比考虑其他范围。就那一次性生成号码来说,这是以毫秒为单位的,那么只要确保这一毫秒之中生成的随机数不重复即可。这个范围可小多了,最多也就上万个。而以小时为单位的,每次生成的时候距离2005年1月1日0时的小时数都不一样,因此每次只需考虑这个小时内生成的随机数是否有重复。这个也小多了。
2、以位为单位穿插、乱序的好处是使号码不具有相邻号码字节相似的特征,缩小为位相似。这个相似是由那个相对稳定并且递增的时间信息引入的。
3、最后用网卡MAC做掩码进行异或,是彻底打乱时间信息的递增特性,导致从连续号码上,即使以位为单位依旧无法看出递增的规律时间位,因为异或后的时间部分已经不具有递增规律了。这个掩码不一定要用MAC,可以是自己指定的一个随机数。但是这个数字要为常量,从第一个号码到最后一个号码所用的这个掩码都必须一样,否则无法确保不出现重复。
4、6个字节可能只用了14位数字,你可以将最后一位数字恒定,将这种算法对应0,以后有新的算法,将最后一位改为1就可以随意使用新的算法,而不会产生与以前生成的号码重复了。
可以这么设计,构成这个序号的原始数据有三组:
15个10进制数可表示的数字,相当于6-7个字节可表示的数字信息。
1。以秒/或分为单位的时间信息
如果你想一次性把几千万号码都生成出来,可以使用毫秒。该值为从系统启动开始至今的毫秒数。
如过你想根据业务发展,每天或每周生成几十万,那么你可以以小时为单位。该值为2006年1月1日至今的小时数。
这个时间信息,2个字节(16位)就够了。
2。随机数
也是一个随机数,我们让随机数的域很大,但是值比较少,因此留随机数4个字节(32位)。
3。网卡MAC信息
随机取网卡MAC的某几位组成第二个不确定因素,6个字节就够了。
然后组合这3个部分。当然不应该以字节为单位,不然太容易看出规律了。因此我们以位为单位:
首先是将时间信息和随机数穿插,这个穿插的规矩是你自己定义的。为了描述方便,我们以T代表时间的位,R代表随机数的位。T2表示时间16位中的第2位,R0表示32位随机数中的第0位。
那么我们可以这样安排第一个字节:
T4 R8 T3 R7 R3 R10 R6 T2
这样第一个字节是由时间信息和随机数信息穿插而成。任何一个信息的变化都可能导致这个字节的变化,因此很难看出规律。每个字节皆是如此,直到把T0 - T15, R0 - R31都排满6个字节。这6个字节是变化多端但是却无法重复。当然,我们把这6个字节转化成10进制数,就是15个左右的数字了。可以直接用了。
但是为了再提高复杂度,导致即使知道哪些位代表什么意思依旧无法猜测出规律,那么用从网卡中提取的6个字节作为掩码,对刚刚得到的那6个进行XOR异或运算。这样彻底打破时间的递增的规律,使得到的数字更无重复的可能。
重申一下这么算得意义:
1、引入时间的好处,是将号码分段,每次判断重复的时候,只需要判断这个时间值不变的范围内的号码是否重复,而不比考虑其他范围。就那一次性生成号码来说,这是以毫秒为单位的,那么只要确保这一毫秒之中生成的随机数不重复即可。这个范围可小多了,最多也就上万个。而以小时为单位的,每次生成的时候距离2005年1月1日0时的小时数都不一样,因此每次只需考虑这个小时内生成的随机数是否有重复。这个也小多了。
2、以位为单位穿插、乱序的好处是使号码不具有相邻号码字节相似的特征,缩小为位相似。这个相似是由那个相对稳定并且递增的时间信息引入的。
3、最后用网卡MAC做掩码进行异或,是彻底打乱时间信息的递增特性,导致从连续号码上,即使以位为单位依旧无法看出递增的规律时间位,因为异或后的时间部分已经不具有递增规律了。这个掩码不一定要用MAC,可以是自己指定的一个随机数。但是这个数字要为常量,从第一个号码到最后一个号码所用的这个掩码都必须一样,否则无法确保不出现重复。
4、6个字节可能只用了14位数字,你可以将最后一位数字恒定,将这种算法对应0,以后有新的算法,将最后一位改为1就可以随意使用新的算法,而不会产生与以前生成的号码重复了。
答!: 66:
如果在存储过程中计算并插入,效率是特别低的,等待几百万数据插入的结果几乎是无法忍受;
如果在程序里面做几百万次写操作,排队丢掉的重复性数据,操作的次数会更多,效率也是没法保证
推荐一个方法:
先设好运算规则,将算出的字符串写到文本文件里面,不用判断是否有重复,几百万条数据应该几分钟就可写完,在实际需要的数量上按一定的比例多生成一些,如10%;然后将这些数据导入数据库,这个过程也是很快的;最后在数据库中将重复数据删除,取需要的数据即可,这步操作同样很快,并且对服务器、运行程序的机器都没有压力
如果在程序里面做几百万次写操作,排队丢掉的重复性数据,操作的次数会更多,效率也是没法保证
推荐一个方法:
先设好运算规则,将算出的字符串写到文本文件里面,不用判断是否有重复,几百万条数据应该几分钟就可写完,在实际需要的数量上按一定的比例多生成一些,如10%;然后将这些数据导入数据库,这个过程也是很快的;最后在数据库中将重复数据删除,取需要的数据即可,这步操作同样很快,并且对服务器、运行程序的机器都没有压力
答!: 67:
如果可以避免,尽量不要通过数据库的重复判断功能来做这种去重复的工作。数据库的重复判断功能是general的,对于这种仅仅生成一个数字的情况效率很低。
而且,对于几百万条数据进行去重复判断,这个生成的复杂度会是O(n^2),显然不合理。
因此,应该采用通过策略避免重复,并且通过分段减小可能重复的域。这样的计算复杂度也就是O(n)。
而且,对于几百万条数据进行去重复判断,这个生成的复杂度会是O(n^2),显然不合理。
因此,应该采用通过策略避免重复,并且通过分段减小可能重复的域。这样的计算复杂度也就是O(n)。
答!: 68:
12345+abcdefg+123abc
这样随机行么?
这样随机行么?
答!: 69:
私底下建议lz使用一下pgp,也许会有些感悟。偶不知道他的硬盘加密部分如何实现,不能忽悠,
只能推荐你去看看。
只能推荐你去看看。
相关JAVA教程:
十万火急,谢谢大家了
小弟初学HIBERNATE请教一个小小的问题
求助!怎样用java调用ocx控件?在线等
JSP 取值
SPRING配置文件出错的问题
怎样获得一个类别下所有的子孙类别?
初学接口自编的有点小问题
用过gSOAP的请进...
我用Digester组件从xml里读出数据,然后插入数据库,老是出问题,请高手指点!!!
请问,有没有用来合并折分pdf的jar包
struts action 中能不能进行 数据类型转换
哎。。。郁闷的问题