现在好多人不想在每个网站都使用相同密码,他们又无法记住所有网站的密码。
本文提供一个简单的方式让大家可以轻松记住一个账户和密码,来得到对每个不同的网站有一个对应的密码。
本文还发在我自己搭建的博客: 生成密码,因为csdn的文章更新没有自己博客简单,所以如果想看更新的文章,请到我的博客去看。
当然自己的博客是放草稿的,如果文章写好了,我才发到csdn
这是一个生成密码算法。
首先是要求用户输入他要记住的账号和密码。
然后用户对他每个需要生成密码的网站,在程序输入域名。
接着就是选择生成的密码,有需要位数N,一般是6,8,10,16的长度。
然后就可以生成一段对应的密码。
生成密码的要求,就是用户需要密码包括的字符,一般有需要大写、需要小写、需要数字、需要特殊,我们把用于选择需要生成类型数记为n。也就是用户如果要求有英文大小写和数值,那么n=3。n用于生成密码中间变量,可以得到所有用户要求。
对于不同的域名可以生成不同的密码,除了域名,还可以使用其它的字符。那么算法的要求是对于不同的输入,很少会生成相同的密码。对于相同的输入,生成相同密码。
于是用户需要记住的就是他的账号密码,遇到了在网站输入,就输入网站,于是得到网站密码,这样可以让用户只记住一个账号就可以。
算法也比较简单,实现有点复杂。
算法:
可以分为3步,第一步是生成组合字符,第二步进行混淆,第三步生成密码。
第一步的作用是生成作为密码的字符,第二步是防止第一步密码过于简单,防止可以从生成密码计算出用户账号密码,第三步是核心,用于生成密码。
- 生成组合字符
第一步需要先计算中间的值,计算方法:
根据生成的中间值,可以计算出字符串s作为密码的生成字符,s的生成算法如下:
生成一段字符串
最后还是需要把字符转数值,这里只是为了方便说明,实际可以直接就是数值放进去,但是注意分割时,需要拿一个8位数。也就是最大是255,用户要求所有字符加起来的值小于255,所以可以选8位,如果觉得这个选择太大,可以使用自己计算的方法。
假如生成md5的是49541A094FE0300DB87109AFEB306207
其中的每一个字符表示16进制数值。
于是两个两个拿出来按照顺序放到s中。两个两个拿出来可以作为混淆,虽然现在md5可以被破解,但是生成密码是无法得到用户的账号和密码和输入域名,所以不需要担心。
- 进行混淆
上面得到的s可能不够复杂,于是需要对上面生成的s进行混淆,混淆可以使用我的加密算法进行混淆。
使用之前的我写的哈希算法,可以把s混淆。
使用方法是申请一段缓存区,使用任意的哈希算法,进行哈希乱序,哈希乱序使用的密码是用户输入的密码。
之前的哈希算法存在哈希乱序、填补空白、字符加密,这里只需要进行哈希乱序。输入是s,和用户输入的密码,输出是乱序的 t 。
但是不需要进行填补空白和加密字符。
乱序之后,需要拿出来,拿出来的做法是去掉所有空白部分。使用如下算法,可以获得乱序的s:
首先清空s,然后
循环缓存区,判断当前字符是否是空白,如果不是空白,那么添加进s
这样,得到乱序的s字符串。
虽然得到s可能和没有混淆是一样的,但是这一步即使不加上也是没有问题。
得到的s字符串还不可以作为密码,需要进行最后一步。
- 生成密码字符
生成密码字符的难点,如何对应 s 的字符和生成密码的字符。
s 的字符是16进制数值,那么就是表示很少的区,但是可以通过使用两个字符可以表示255个字符,基本用户的要求可以得到。
把s按照两个字符分割,得到48个子字符串s1[],每个s1都是有两个字符。这里的s1是一个数组,包括48个字符串。
两个字符可以算出所有用户要求的字符,可以看到这个方法的不好的地方在于有些字符被用到概率比较高。
所以还需要一个变量记录 a ,用于计算用户要求不同类型出现数,在得到字符步骤,对字符进行偏移。偏移的意思:先把字符组成环,然后把字符向右偏移 a 个字符。
计算生成密码字符串S算法如下
循环所有 s1
首先将要求所有类型字符分区域,计算总数l,转换s1字符为数值。
对s1取模l,得到对应数所在区域。添加a[区域]+1,对应字符向后移动 a[区域]。
得到的字符添加到 S
首先对 a 进行解释:
首先把要求所有字符写成环,把获得字符向右移动a,得到字符。原先是n移动5得到s。
先说一个例子,对于区域和对应字符需要做解释。
假如用户要求有3种,英文、数值、特殊符号
假如英文数量有 25 个,数值有 10 个,特殊符号有10个
那么组成的线大小是 l 25+10+10=45
对应英文区是 [0,24] 对应数值区是[25,34] 对应特殊符号区是 [35,44]
两个16进制字符最大值是 255
所以先把两个字符转数值 n
对n取模l,得到x。那么在l中,x一定会在某个区域,判断x落下区域。
添加对应区域 (a[区域]+1) 对应字符,如果字符超过区域,那么对字符取模,得到的值添加到S。
循环直到结束。
就可以获得S密码字符。
假如 s1[0]=49 s1[1]=54 ,这里不是十进制
那么第一个字符取模得到 28, 第二个得到 39
那么第一个字符所在位置是 数值区,于是 a[数值]+1=1
28+1对应数值区的’4’,于是记录到S+=’4’
第二个字符所在区是特殊字符区,a[特殊]+1=1
39+1 对应特殊的’$’ 于是记录到S,这里,我特殊字符的排序没有给出来,实际的排序可以任意排序,但是特殊字符排序是算法中固定的。
这样就得到 S=4$
继续计算就可以得到S。
这样算法对于计算首先是对于区域进行计算,可以得到落在不同区域的概率是不同的,这是算法的缺点,但是和现实需要是一样的。
网站让用户输入英文和数值,那么比较多的人会输入英文数多于中文,这是某大神提供的。
接着计算S是否包含有用户选择的所有类型,如果存在一个类型没有存在,那么使用哈希S+=has(类型)
添加一个类型到字符串最后。
这个算法是可以让生成的S包含所有类型。虽然一般需要的类型都可以生成,但是有些输入可以存在某些类型不存在,于是需要让S添加所有存在的类型。假如生成的S只有英文和数值,没有特殊字符,但是用户需要特殊字符,那么就需要这个算法来得到特殊字符。得到的特殊字符需要和用户输入关联,所以需要has算法。
如何识别存在哪些类型,哪些没有,编码难度还是比较高,但是不难做,一次循环就可以做到,只是定义的数据结构相对比较难。当然,相信花10分钟还是可以想出来,这是我做过的ACM有的。
其中has函数为
char has(类型)
{
var h = 3655; 这是一个大的数,工程经验
var a = 0;
var b = Int.Max;这是最大的一个数
var str=new {x,x1,x2};//直接组合中间值
foreach(s:str) 循环str
{
foreach(t:s) 循环所有字符
{
h=(a+t)&&b || (a+t); 算法是选一个哈希算法,可以选择其他
a=b<<t;
b=b<<t;
}
}
return (char)(h%(类型上限-类型下限)+类型下限+1);
}
has就是生成一个类型随机的字符,当然随机只是说生成的很难猜出,只要给出一样的输入,得到的字符是一样的。
接着就是从S里得到生成密码,生成密码就是给用户的密码。用户可以用生成密码做他需要使用的域名的密码。
取出生成密码算法:
取长度
N就是需要生成密码的长度,n就是选择类型数。
假如用户需要生成长度为5,需要英文、数值和特殊,那么得到 l=2
我们将会在S取出前l个字符,之所以要取出前l个,是因为用于必须要有类型,如果取出来的字符没有存在一个被选择类型的,那么在最后加类型。
循环密码k=S[0,l]
,如果k存在不包含选择的类型,那么继续往s[l]
之后的字符找,找到第一个选择的类型,放入k,直到所有类型都被找到。
如果这时密码的长度小于N,那么往下取 s[l]
的字符,直到密码长度为N。
假如生成的S是 4$5123123123123123123123a
用户需要的长度N=5
于是计算 l = 5-3=2
取出S前 2 字符 4$
判断存在类型 数值和特殊,于是剩下英文,从2开始向后寻找,直到第一个英文,找到a
,于是得到4$a
。判断不存在的类型,已经所有类型都存在,于是继续往下拿字符,直到N。l之后的字符是512312312
,最后得到4$a51
这就是密码生成算法。
但是可以看到,如果用户需要一个域名多个账户,也就是需要一个域名有多个密码,那么上面算法就无法得到。如果用户输入一个密码,一段时间想换新的密码,上面算法也无法得到。所以算法需要用户再输入一个数值,表示这是第多少次的密码。
所以用户的输入就包括:
用户账号
用户密码
域名
要求
备用
其中最后一个备用就是让用户输入这是第n次生成密码,也就是前面第n次都是他不喜欢的,或者使用的。
那么算法需要做哪些调节?
首先在开始的生成s算法,把组合改成
这样就可以。
上次申请ca发现这个算法和LassPass算法差不多,只是使用我之前的算法混淆和一些地方不同,但是基本流程相同,可以认为这个算法是比较好的,可以自己试试写自己的生成密码算法。
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。