以前的做法是用for循环随机地获取一个个字符后再拼接起来
今天在网上看到一个非常简练的写法,在这里分享一下
import os
def randomString(n):
return (''.join(map(lambda xx:(hex(ord(xx))[2:]),os.urandom(n))))[0:16]
print randomString(16)
这些函数之前都没见过,之前接触的python内建函数比较少...
- os.urandom(n) : 随机生成n个字节的串,一个字节是8位,我猜是这8位二进制数是随机的,所以这个字节也是随机的。所以没有指定的编码方案可以很好地把所有这个字符串显示转换成功,即有可能会乱码
- 再介绍一下map函数,它的第一个参数是一个函数(可以说是一个映射函数),第二个参数是一个元组或者列表(iterative),它将iterative的每个元素作为参数依次传入映射函数,将所有返回值分别作为元素,最后形成一个列表返回。
- ord(xx):以一个字符(python是一个字节也即8位),计算其unicode 码值的十进制表示,比如字符a,unicode code是0x0061,则ord('a')则返回97,因为十六进制的61等于十进制下的97
- hex(xx): 就是把十进制的数转换成十六进制串,比如hex(97)则变成 '0x61’. 这里我们不需要前面的‘0x',所以做切片[2:0]
- 最后拼接map返回的随机元素列表后就是一个随机的字符串了
在os.urandom(n)这一步可以产生255种字符,因为一个字符的8位二进制数是随机分配的。由指定的n,则可以生成长度为n的,由255种随机字符组成的字符串。
lambda只是将我们生成的字符串的每个字符转换成我们可视的有数字和字母组成的长度为二的字符串
hex把一个8为的字符转换成1个或2个字符,并且不会输出类似0x0e这样的串,因为它会输出成0xe,所以最好做一次做一次切片
因为每个随机字符最少会被转换成1个字符,所以做切片不会遇到长度不够长的情况,而且由于os.urandom(n)是在bit的级别上的随机,应该保证了随机性