我想生成一个随机字符串(例如密码,用户名等)。应该可以指定所需的长度(例如13个字符)。

我可以使用哪些工具?

(出于安全和隐私的原因,字符串最好是离线生成,而不是在网站上在线生成。)

评论

AskUbuntu已经提供了很好的答案。 (我个人使用apg。)

@Sparhawk AskUbuntu问题/解答更多关于列表工具。请考虑在此处添加答案,以展示如何使用apg生成随机字符串。

在计算机上使用随机数生成时要谨慎。有些随机数的出现远少于它们的出现,但是要说出“好”和“坏”随机数生成之间的区别是很难的。

@Sobrique关于伪随机数生成器(例如/ dev / urandom)的出色观点。使用真正的随机数生成器,例如基于random.org。

笑话答案:要生成真正的随机字符串,请将新用户放在Emacs(或Vim)的前面,并要求他们退出。 ;)

#1 楼

我最喜欢的方法是使用/dev/urandomtr删除不需要的字符。例如,仅获取数字和字母:
tr -dc A-Za-z0-9 </dev/urandom | head -c 13 ; echo ''

或者,包括OWASP密码特殊字符列表中的更多字符:
tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' </dev/urandom | head -c 13  ; echo

如果tr遇到问题,请投诉关于输入,请尝试像这样添加LC_ALL=C
LC_ALL=C tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' </dev/urandom | head -c 13 ; echo


评论


或者这样做:head / dev / urandom | tr -dc A-Za-z0-9 |头-c10-这种方式更准确。您会获得10个大写,小写或数字字符

–白兰地
2015年9月19日在8:47

第一个头命令可能有问题。它将从/ dev / urandom输出前10行,这意味着一旦看到第10行,它将停止。因此,发送到tr命令的输出长度是随机的。 tr的输出中可能少于13个字符。我还没有计算出发生这种情况的可能性,计算有些棘手。

–卡巴斯德
2015年9月19日在22:40

最好这样做:
– PSkocik
2015年9月20日下午13:06



+1这是快速尝试从OWASP密码特殊字符页面中包含其他字符的信息,已为bash命令行转义:tr -dc A-Za-z0-9 \!\“#$ \&\'\(\)\ * +,-。/ \:\\\\\; \ <= \> \?@ [] ^ _`{\ |}〜

–Rup
16年7月28日在10:26

+1为LC_ALL = C解决方法。在我的情况下,头文件/ dev / urandom | LC_ALL = C tr -dc A-Za-z0-9 | head -c 13)修复了OSX tr问题。

– Camilo Sampedro
18-09-28在10:14

#2 楼

我正在使用openssl命令,这是瑞士密码术的军刀。

openssl rand -base64 12




openssl rand -hex 12


评论


rand -hex会将输出限制为仅16个字符,而不是键盘上的90+个字符。 base64更好,因为它是64个字符,但不是随机的(例如,存在可预测的填充模式,也许某些字符比其他字符出现得更多)。

–马丁·图尔诺伊(Martin Tournoij)
16-8-27在17:37



@Carpetsmoker:请注意,示例openssl rand -base64 12产生16个字符的输出(因为256个值映射到64个)。十六进制示例产生24个字符。十六进制的情况是没有损失的,因为它是一个简单的1:2映射,但是在base64的情况下可能会有所损失,因为使用了填充。基数不影响随机性,而是一个映射到另一个的方式。 (总位数非常重要)。

–丹尼斯·威廉姆森
17年5月19日在20:29

问题是“如何生成特定长度的随机字符串” @DennisWilliamson,因此尽管您的评论是正确的,但在此问题的上下文中是不正确的。

–马丁·图尔诺伊(Martin Tournoij)
17年5月19日在20:31

这个答案值得更多的赞扬。 urandom,pwgen,gpw等在您的系统上可能可用或不可用;同样在不同的环境中,适用于一个策略的策略可能不适用于另一个策略。没有openssl,这将是一个非常不正常的设置。更好:openssl rand -base64 32 | tr -d / = + | cut -c -16这将为您提供32个字符减去非字母数字,并修剪为16个字符长度。使其易于以管理员身份处理。用户只有字母数字(他们倾​​向于使用字母数字)。该长度足够长,以至于特殊字符的去除不会过度影响熵。金色的

– zentechinc
17年9月5日在16:34

请注意,根据其手册,openssl rand命令仍然是伪随机生成器,因此不是加密安全的。这适合我的需求,但可能不适合所有应用程序的需求,例如初始化IV,如另一条评论中所述。

–spikyjt
2月25日15:09

#3 楼

要生成随机密码,您可以使用pwgen:pwgen生成随机,无意义但可发音的密码。
这些密码仅包含小写字母或大写
,并且
放置小写字母或数字。
以大写字母和数字的方式放置,使
仅记住单词时便记住其位置。


7个密码,长度为13:

geek@liv-inspiron:~$ pwgen 13 7
Eu7Teadiphaec giepahl3Oyaiy iecoo9Aetaib4 phaiChae6Eivi athoo3igee8Co
Iphu4ufeDeelo aesoYi2lie9he 


如注释中所述,您可以通过使用-s参数来避免降低熵(即生成更安全,完全随机但难以识别的密码)记住密码):

geek@liv-inspiron:~$ pwgen -s 13 7
eAfycrPlM4cYv 4MRXmZmyIVNBp D8y71iqjG7Zq7 FQRHcserl4R8O yRCUtPtV3dsqV
0vJpp2h0OrgF1 QTp7MKtJyTrjz 



要生成随机用户名,您可以使用gpw


该软件包生成明显的密码。它使用
从您提供的任何字典中提取的三个字母组合(字母)的统计信息。


生成7个长度为13的密码(用户名) :

geek@liv-inspiron:~$ gpw 7 13
sreepoidahsas
risadiestinge
ntodynesssine
deodstestress
natinglumperm
riasigentspir
enderiferback


评论


+1表示不重新发明轮子。如果您不希望减少“可发音”约束的熵,只需使用pwgen -s。

– Nate Eldredge
2015年9月19日下午16:21

太糟糕的pwgen不包含在标准bash版本中。

–克雷格·希克斯(Craig Hicks)
6月6日16:56

#4 楼

这是我的方法。它生成10个字符的随机字符串。您可以通过使用其他字符串处理工具替换“ fold”来对其进行优化。

cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 1


评论


+1这个答案是POSIXly正确的,当然要减去/ dev / urandom的使用

– Harold Fischer
19-2-26的3:17

#5 楼

为了使用每个发行版中内置的标准Linux工具生成具有最高熵的密码,我使用:

< /dev/urandom tr -cd "[:print:]" | head -c 32; echo


这将输出所有ASCII可打印字符-从32(空格)到126(波浪号,~)。密码长度可以通过head-c标志进行控制。 tr中还有其他可能的字符集(不包括空格,仅字符33-126,请使用[:graph:])。

评论


这与现有答案有何不同?具体来说,赫伯特想到了。

–狐狸
17-4-27在22:40



@Fox他的解决方案使用字符的硬编码列表,由于代码的可读性,紧凑性和简洁性,因此不鼓励使用这种编程习惯。 bash还可以解释某些特殊的可打印ASCII字符,更不用说他的一个衬里最明显的缺点-如果需要最大的熵,可以确定所有可用字符都包含在列表中吗?而且没有重复可能改变tr的行为吗?既然你问过,他的回答就应该由我来代替:)

– drws
17年4月29日在13:37

许多(如果不是大多数)网站都对密码中的字符有限制,因此对我来说,硬编码'[:print:]'并不比对OWASP密码特殊字符列表进行硬编码更好。我觉得这里几乎每个答案都可以通过使用变量来改善,但这是一个很小的变化,我只建议进行编辑

–狐狸
17年4月29日在13:54


–mzzzzb
18 Mar 8 '18 at 14:36

@RyanKrage:graph:已经排除了空间,所以比:print:更好的解决方案。

–Dani_l
2月16日上午10:14

#6 楼

受Pablo Repetto的启发,我得到了这个易于记忆的解决方案:

shuf -zer -n20  {A..Z} {a..z} {0..9}


-z避免了多行输出

-e回显结果

-r允许任何字符多次出现

-n20个长度为20个字符的随机字符串

{A..Z} { a..z} {0..9}允许的字符类

shuf是linux coreutils的一部分,广泛使用或至少已移植。

评论


这里的一个问题是“ -z”,因为它不会“避免多行输出”,而是在每个字符串后附加\ 0而不是换行符。通过添加“ | od -xc”对其进行测试。您可以使用tr删除零个字符:shuf -zer -n20 {A..Z} {a..z} {0..9} | tr -d'\ 0'

– ke
6月16日下午5:37

要在鱼壳中运行此命令,请使用bash -c'shuf -zer -n20 {A..Z} {a..z} {0..9}'

– Baldrs
9月1日13:29

#7 楼

根据您想要的随机性级别,您可以简单地使用内置了zsh变量的bash(也可能是ksh$RANDOM):

/dev/urandom要简单得多,但是为了完整起见,您也可以使用$RANDOM

$ echo $RANDOM | tr '[0-9]' '[a-z]'
bfeci
$ echo $RANDOM | tr '[0-9]' '[a-z]'
cijjj


重要:此解决方案仅会使用前10个字母生成随机字符串字母表。是否足够满足您的需要取决于您的需求。

评论


您如何控制生成的字符串的长度?

–landroni
2015年9月19日下午13:33

@landroni我认为除非长度合适,否则您不能缺少循环。 $ RANDOM将打印一个介于0和32767之间的数字。

– terdon♦
2015年9月19日下午13:36

我已经尝试运行该命令约20次,但我得到的任何信息都不能超过4-5个字符。

–landroni
2015年9月19日下午13:38

@landroni谢谢,我已经添加了一种指定长度的方法,但这不是很好。我只是使用rand = $(head -c 100 / dev / urandom | tr -dc A-Za-z0-9 | head -c13)之类的东西代替。

– terdon♦
2015年9月19日下午16:12

@SkippyleGrandGourou非常好。我将此添加到答案中,谢谢。

– terdon♦
19年5月8日在11:30

#8 楼

使用xxd命令指定长度(通过-l),该长度在Linux和OS上均适用。
https://www.howtoforge.com/linux-xxd-command/

 xxd -l16 -ps /dev/urandom
 


#9 楼

在某些Linux发行版中默认包括APG

要在Special,Numeric,Capital和Lower子集中生成大小为5到10的密码,命令为:

apg -MSNCL -m 5 -x 10


并返回

@OpVeyhym9
3:Glul
3DroomIc?
hed&Os0
NefIj%Ob3
35Quok}


@landroni在评论中说。

评论


以下是生成包含许多特殊字符的随机14个字母密码的选项:apg -a1 -m14

– Neuhaus
17年11月11日在19:10

#10 楼

@Brandin在对另一个答案的评论中解释了如何使用/dev/urandomhead -c 100获得最多100个字节。另一种方法是使用dd

tr -dc A-Za-z0-9 < /dev/urandom | dd bs=100 count=1 2>/dev/null


2>/dev/null命令末尾的dd是禁止显示“ ...记录/ ...记录out”输出。

我不知道这两种方法之间的任何实质性优点/缺点。

我对tr的这两种方法都抱怨输入有问题。我认为这是因为它不喜欢接收二进制输入,因此建议先使用/dev/random过滤iconv -c -t US。但是,吉尔(Gilles)提出了一种不同的诊断和解决方案,对我有用:

LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | dd bs=100 count=1 2>/dev/null


评论


出于某种原因,iconv解决方案最大化了一个CPU内核,但未产生输出(我等了10秒钟才杀死了它)...

–landroni
2015年9月19日在9:38

在我的Ubuntu 14.04系统上,libc-bin 2.19提供了iconv。我不确定是否是相同的图标...

–landroni
2015年9月19日下午13:36

tr支持二进制输入。但是,区域设置可能会影响A-Z之类的范围。尝试LC_ALL = C tr…

–吉尔斯'所以-不再是邪恶的'
2015年9月19日在20:27

@Gilles根据POSIX规范,它不“支持二进制输入”。只有GNU tr支持,因为它根本不支持多字节(例如,上次我检查它的大小写更改是通过简单地设置每个字节的第六位来实现的)。其他系统(例如BSD)确实支援多位元组,因此在这里会失败,因为在大多数编码方式中,随机输入流也是有效的多位元组流的机会非常小。 GNU可能会在任何给定时刻添加多字节支持,这将失败。当然,设置LC_ALL = C将解决此问题。

–马丁·图尔诺伊(Martin Tournoij)
16年8月27日在17:33

@Carpetsmoker POSIX确实需要tr来处理二进制输入(在C语言环境中)。 (好吧,它只明确表示要支持空字节,不是说要支持不以换行符结尾的非空文件,但实际上,情况总是如此。)

–吉尔斯'所以-不再是邪恶的'
16年8月27日在17:57

#11 楼

您可以使用具有此目的的md5工具之一。如果创建完全随机的密码,则可以使用md5pass。这是一个非常简单易用的工具,对您很有帮助,因为您可以将“普通文本”与“盐”一起使用以跳跃方式构造相同的密码,然后在以后恢复该密码,或者,您可能希望获得一个完整的密码。始终提供随机密码。通用用法是:
md5pass [password] [salt]


其中password是一个选择的单词,将用于构建随机字符串,而salt是要使用的字节跳数。像这样:

md5pass word

$.MUittVW$j.XDTF1QRnxqFdXRUiSLs0


这将创建一个“随机序列”密码供您使用。如果不使用salt,则以后可能无法重新创建相同的字符串。

但是,如果您使用salt像这样:
br />然后您可以创建一个序列,如果将该词与最初定义的相同盐(或跳跃)结合使用,则可以恢复该序列。

评论


当使用盐时,这听起来类似于PasswordMaker方法...

–landroni
2015年9月26日在8:20



-是的听起来可能类似于一个制造商的密码,但是区别在于它不是商业程序或其他任何东西,因为这里涉及的md5工具集“ md5pass,md5sum,md5sum.textutils”受到关注并且对系统可用不花一分钱!

–笑话不错
15年9月26日在13:17

实际上,我想到过PasswordMaker,它也是开源且非商业的。

–landroni
2015-09-26 16:43



#12 楼

我使用:
base64 < /dev/urandom | tr -d 'O0Il1+/' | head -c 44; printf '\n'
这给了我57个可能的字符。该字符串可以复制粘贴(删除+和``)或打印并重新输入,因为已经删除了难以区分的字符(I1lO0)。

44个字符给出了我:log2(5744)> 256.64熵位
22个字符给我:log2(5722)> 128.32熵位

我喜欢这样做,因为:
它使用标准的系统工具-没有额外的二进制文件
不会“浪费”太多的随机性(使用接收到的89%的随机位,而将其直接输送到tr的解决方案则使用〜24%)
22个和44个字符非常好地配对(恰好高于)两个断点的公功率
可以轻松地选择并粘贴或打印输出,并以最小的人为错误率重新键入输出
,比十六进制编码的短(32和64而不是22和44)解决方案,例如md5sum / sha1sum等。 br />

评论


如果您需要数字/特殊字符-通常会有一个数字,如果不需要,您可以安全地附加1而不会降低熵(生成一个新的数字以获得一个w / a的数字确实会降低熵)。您也可以安全地附加!而不降低熵。两种方案都不会增加熵的价值,但是会使生成的字符串符合较早的密码要求。

– Iiridayn
18-10-17在21:28

它可以在macOS上运行!

–米卡·亨宁(Micah Henning)
5月2日,2:56

#13 楼

这两个命令分别生成随机密码和密码短语。

shuf --random-source=/dev/urandom --repeat --head-count=20 file_with_characters | tr --delete '\n'

shuf --random-source=/dev/urandom --repeat --head-count=7 file_with_words | tr '\n' ' '


密码生成器需要一个file_with_characters,其中包含您希望密码使用的所有字符,每行一个字符,每次精确地一次。该文件不能包含空行,并且行必须以换行符结尾。

密码短语生成器需要file_with_words,其中包含您希望密码短语使用的所有单词,每行一个单词,并且一次每。该文件不能包含空行,并且行必须以换行符结尾。

--head-count选项指定密码的长度(以字符为单位)或以词组表示的密码。

#14 楼

我发现在macOS上将/ dev / urandom传递给tr无效。这是另一种方法:

set="abcdefghijklmonpqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
n=6
rand=""
for i in `seq 1 $n`; do
    char=${set:$RANDOM % ${#set}:1}
    rand+=$char
done
echo $rand


评论


检查我的答案的最后一个例子。它不使用tr。 unix.stackexchange.com/a/494931/203075

– Zibri
19年1月17日在11:18

#15 楼

我想贡献我的常用命令来生成密码

$ cat /dev/urandom | base64 | head -n 1 |tr -dc '[:alnum:]' |cut -c -13
b0R55751vWW9V


要配置密码的长度,请将cut命令中的数字更改为所需的长度,例如24个字符

$ cat /dev/urandom | base64 | head -n 1 |tr -dc '[:alnum:]' |cut -c -24
WFBhVHuKbrnRhd5kdWXPzmZG


不想混淆0或O,1或l?用另一个tr过滤掉它

$ cat /dev/urandom | base64 | head -n 1 |tr -dc '[:alnum:]' | tr -d '0O1l'|cut -c -24
JuCphwvhrhppD9wVqfpP2beG


我个人从来都不喜欢密码中的特殊字符,这就是为什么我只选择[:alnum:]作为我的密码生成器的原因

#16 楼

在这种情况下,Unix的哲学“很多可以做一件事情的小工具”非常适合您。



/dev/urandom是随机的“字节”流(包括base64将字节数据编码为[A-Za-z0-9/+](完全可打印)

块计数)

OSX

base64     < /dev/urandom | dd bs=1k count=1


Linux

base64 -w0 < /dev/urandom | dd bs=1k count=1


注意:


如果需要字符的子集,可以在管道中插入修饰符。


例如:dd摆脱大写字母和tr -d '[A-Z/+]'+



您可以将/(块大小)设置为所需的任何长度。除非需要,必须用bs重置。


#17 楼

我的密码非常安全(密码长度为16)的方法:

cat /dev/urandom | tr -cd [:graph:]|head -c 16


示例结果:

jT@s_Nx]gH<wL~W}

<或者,生成多个密码:

cat / dev / urandom | tr -cd [:graph:] | fold -w 16 | head -6

示例结果:

7ck%G7'|f&}_8(]s
<?*]E.CG[NB'gK#A
:tF-WPTOa3!i7S(h
2xy(>=%3=Kb1B$`6
*98Lf{d?Jzb}6q1\
E7uCEAN2Hz]]y|5*


安全性稍差(较小字符集):

cat /dev/urandom |base64 -w 0|fold -w 16|head -6


示例结果:

rJqYxYZLOTV+A45w
PUKQ+BoBf6yfZw5m
+LRfpsN9CsLRiN8V
yMS6zDpL6NHmG17s
yTUWPG7Rum97schi
cognvjVwaKaAyPRK


#18 楼

我在Alpine Linux中维护secpwgen,并将源保存在我的Github上。

它可以产生随机字符串或diceware短语:

musl64 [~]$ secpwgen
USAGE: secpwgen <-p[e] | -A[adhsy] | -r | -s[e]> N

PASSPHRASE of N words from Diceware dictionary
  -p    generate passphrase
  -pe   generate enhanced (with symbols) passphrase

SKEY PASSWORD of N words from S/Key dictionary
  -s    generate passphrase
  -se   generate enhanced (with symbols) passphrase

ASCII RANDOM of N elements (at least one option MUST be present)
  -A    Each letter adds the following random elements in output:
    a    alphanumeric characters
    d    decimal digits
    h    hexadecimal digits
    s    special characters
    y    3-4 letter syllables

RAW RANDOM
  -r    output BASE64 encoded string of N random BITS
  -k    output koremutake encoding of N random BITS


要生成13个字符的随机字符串,您可以使用:

musl64 [~]$ secpwgen -Aas 13
----------------
WK5#*V<]M3<CU ;ENTROPY=67.21 bits
----------------
INFO: destroying random number generator.
INFO: zeroing memory.

musl64 [~]$ secpwgen -Aa 13
----------------
GP0FIEBM9Y3BT ;ENTROPY=67.21 bits
----------------
INFO: destroying random number generator.
INFO: zeroing memory.


为了让用户记住密码,请使用骰子短语:

musl64 [~]$ secpwgen -p 5
----------------
wq seen list n8 kerr  ;ENTROPY=65.00 bits
----------------
INFO: destroying random number generator.
INFO: zeroing memory.


我个人喜欢:

musl64 [~]$ secpwgen -r 512
----------------
h62lL7G4gwh3/j9c7YteQvVXoqJrQKKPWVR3Lt7az36DcfWZWtUgBT19iwmJBwP4UahNzPe7qYD7OcklUFpCzQ== ;ENTROPY=512.00 bits
----------------
INFO: destroying random number generator.
INFO: zeroing memory.


#19 楼

到目前为止,没有一个答案是真正的跨操作系统。

主要缺陷由语言环境定义(MacOS情况)和tr无法识别字符间隔(Solaris情况)表示。 >
您应该尝试shlibs。它是真正的跨操作系统的操作系统。
获取随机字符串的代码是shlibs str005./shlibs str005)。

获取50个字符的随机字符串,包括标点符号,排除数字:

shlibs str005 50 -p -xd


#20 楼

要在MacOS上使用投票最高的答案,可以使用
LC_CTYPE=C tr -dc A-Za-z0-9 < /dev/urandom | head -c 32

,其中LC_CTYPE=C将限制tr的字符集,而32是长度。

#21 楼

一种超简单的方法(可能比您想要的简单)可以实现此目的,即生成给定范围内的随机数,将该数字转换为等效的ASCII字符,然后将其附加到字符串的末尾。

这是Python中的一个基本示例:

 import random # import random library  
passFile = open("passwords.txt", 'w') # create file passwords.txt
passNum = int(input("Number of passwords: ")) # get number of  passwords
passLength = int(input("Password length: ")) # get length of passwords  
for i in range(passNum):
    password = "" # reset password
    for i in range(passLength):
        num = random.randint(65, 122) # get random number
        while num in range(91, 97): # Don't include punctuation
            num = random.randint(65, 122)
        password += chr(num) # add character to current password 
    passFile.write(password + "\n") # add current password to file  
passFile.close() # close file
 


EDIT :添加了注释,并添加了生成多个密码并将其写入文件的代码

评论


如果拥有Python的功能,我将不会以这种方式做到这一点。在包含所有对密码有效的字符的字符串上使用联接,并使用random来选择字符会容易得多。

–麦克·麦克马洪(Mike McMahon)
2015年9月20日5:20



最好像这样使用Python.activestate.com/recipes/578468-password-generator-mkpasswd

–吉列什·乔汉(Grijesh Chauhan)
2015年9月21日在9:16

#22 楼

我想要以下命令:

date +%s | sha256sum | base64 | head -c 12


评论


我宁愿使用更多的随机纳秒方法:date +%N因为如果您在脚本中生成许多用户和密码,那么对于许多甚至所有date命令而言,秒数都可能变为相同,从而产生相同的密码。

–约翰市长
17年4月28日在12:53

@JohnMayor:这种方法是否更健壮:dd if = / dev / random bs = 512 count = 1?

– Eugen Konkov
17年4月28日在13:48

这个答案非常危险!您可以从易于预测的已知种子生成密码。我可以生成最近几年使用此方法生成的所有密码,并将此列表用于暴力破解。

–流程
17年7月1日在17:20



#23 楼

我去了
http://passwordsgenerator.net/
它允许生成最多2048个字符的随机字符字符串,选择大写,小写,数字0到9,标点符号或任何组合。

评论


我已经澄清了这个问题,以明确表明离线生成的字符串更可取。直接在网站上生成密码是不安全的,特别是如果连接不是HTTPS(如您的回答)时。

–landroni
2015年9月26日在7:09

从互联网上获得随机密码非常愚蠢和幼稚。现在,有人知道您用于某些服务或站点的密码以及有关您的唯一个人详细信息(IP地址,浏览器/环境信息)。现在,该站点可以将信息与收集到的有关您的其他数据进行交叉引用。例如,您曾经张贴到邮件列表,您的IP地址在邮件的标题中,因此我们现在有了密码,名称和电子邮件地址...您真的在这里信任随机陌生人的密码。

–马丁·图尔诺伊(Martin Tournoij)
16年8月27日在17:35