linux - 改进我的密码生成脚本

标签 linux bash passwords

我创建了一个小的密码生成脚本。我很好奇可以对其进行哪些改进输入错误处理、使用信息等。这是我有兴趣看到改进的核心功能。

这就是它的作用(也是我喜欢它做的):

  1. 让更改密码中使用的小写字符 (L)、大写字符 (U)、数字 (N) 和符号 (S) 变得容易。
  2. 我希望它能在最多两秒内为我找到长度为 10 的新密码。
  3. 它应该以可变长度的密码字符串作为参数。
  4. 只应接受包含至少一个 L、U、N 和 S 的密码。

代码如下:

#!/bin/bash

PASSWORDLENGTH=$1
RNDSOURCE=/dev/urandom
L="acdefghjkmnpqrtuvwxy"
U="ABDEFGHJLQRTY"
N="012345679"
S="\-/\\)?=+.%#"

until [ $(echo $password | grep [$L] | grep [$U] | grep [$N] | grep -c [$S] ) == 1 ]; do
    password=$(cat $RNDSOURCE | tr -cd "$L$U$N$S" | head -c $PASSWORDLENGTH)
    echo In progress: $password # It's simply for debug purposes, ignore it
done
echo Final password: $password

我的问题是:

  • 有没有比我现在的方法更好的检查密码是否可接受的方法?
  • 实际的密码生成怎么样?
  • 编码风格有什么改进吗? (短变量名是临时的。尽管我对“常量”使用大写名称[我知道正式没有],对变量使用小写名称。你喜欢吗?)

让我们投票选出改进最多的版本。 :-)

对我来说,这只是一个练习,主要是为了娱乐和学习经验,尽管我将开始使用它而不是我现在正在使用的 KeepassX 的生成。看看哪些改进和建议会来自更有经验的 Bashistas(我编造了这个词)将会很有趣。


我创建了一个小的基本脚本来衡量性能:(以防有人认为它很有趣)

#!/bin/bash

SAMPLES=100
SCALE=3

echo -e "PL\tMax\tMin\tAvg"
for p in $(seq 4 50); do
    bcstr=""; max=-98765; min=98765
    for s in $(seq 1 $SAMPLES); do
        gt=$(\time -f %e ./genpassw.sh $p 2>&1 1>/dev/null)
        bcstr="$gt + $bcstr"
        max=$(echo "if($max < $gt ) $gt else $max" | bc)
        min=$(echo "if($min > $gt ) $gt else $min" | bc)
    done
    bcstr="scale=$SCALE;($bcstr 0)/$SAMPLES"
    avg=$(echo $bcstr | bc)
    echo -e "$p\t$max\t$min\t$avg"
done

最佳答案

您在输入流中丢弃了一堆随机性。保留这些字节并将它们转换为您的字符集。将循环中的 password=... 语句替换为以下内容:

ALL="$L$U$N$S"
password=$(tr "\000-\377" "$ALL$ALL$ALL$ALL$ALL" < $RNDSOURCE | head -c $PASSWORDLENGTH)

$ALL的重复是为了确保“映射到”集合中有>=255个字符。

我还删除了 cat 的无偿使用。

(经过编辑以澄清上面出现的内容并不是要替换完整的脚本,而只是替换内部循环。)

编辑:这是一个非常更快的策略,它不会调用外部程序:

#!/bin/bash

PASSWORDLENGTH=$1
RNDSOURCE=/dev/urandom
L="acdefghjkmnpqrtuvwxy"
U="ABDEFGHJLQRTY"
N="012345679"
# (Use this with tr.)
#S='\-/\\)?=+.%#'
# (Use this for bash.)
S='-/\)?=+.%#'

ALL="$L$U$N$S"

# This function echoes a random index into it's argument.
function rndindex() { echo $(($RANDOM % ${#1})); }

# Make sure the password contains at least one of each class.
password="${L:$(rndindex $L):1}${U:$(rndindex $U):1}${N:$(rndindex $N):1}${S:$(rndindex $S):1}"

# Add random other characters to the password until it is the desired length.
while [[ ${#password} -lt $PASSWORDLENGTH ]]
do
  password=$password${ALL:$(rndindex $ALL):1}
done

# Now shuffle it.
chars=$password
password=""
while [[ ${#password} -lt $PASSWORDLENGTH ]]
do
  n=$(rndindex $chars)
  ch=${chars:$n:1}
  password="$password$ch"
  if [[ $n == $(( ${#chars} - 1 )) ]]; then
      chars="${chars:0:$n}"
  elif [[ $n == 0 ]]; then
      chars="${chars:1}"
  else
      chars="${chars:0:$n}${chars:$((n+1))}"
  fi
done
echo $password

计时测试表明,该脚本的运行速度比原始脚本快 5-20 倍,而且从一次运行到下一次运行的时间更可预测。

关于linux - 改进我的密码生成脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1466709/

相关文章:

bash - 转换 mp3 -> 带有静态图像的视频 (ffmpeg/libav & BASH)

C++11:map::lower_bound 在 Linux 中对于 2 个或更少的元素不能正常工作

linux - 更新 .sql 文件时 Docker 不更新卷

.net - 告诉 mono/.NET 只使用 X 内存量?

bash - 正确处理文件名中带有空格的文件列表

bash - 为什么我无法指定包含 bash 数组变量长度的序列?

android - 安卓系统如何确认密码?

security - 在 Spring Security 3.1 中,StandardPasswordEncoder 最适合用于加盐密码的用途是什么?

git - 有没有办法让 git 记住 WebDAV Remote 的密码?

c - Linux下实现窗口函数InterlockedExchange