Как я могу сгенерировать буквенно-цифровую строку, используя только POSIX-совместимые инструменты оболочки? - PullRequest
0 голосов
/ 20 мая 2018

Я пытаюсь сгенерировать буквенно-цифровую строку из восьми символов, используя POSIX-совместимые инструменты оболочки.Я пытаюсь использовать / dev / urandom для создания этой строки (кстати, я не знал, что / dev / random и / dev / urandom не указаны в POSIX, но я собираюсь сделать это, потому что они присутствуют в Linux,FreeBSD, Mac OS, AIX и т. Д.)

Существует множество руководств, показывающих, как это можно сделать, но ни одно из найденных мною близко к правильной постановке.В частности, я продолжаю видеть использование head -c (аргумент -c не определен в POSIX), как показано ниже:

head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo ''

Другая проблема, с которой я столкнулся, заключается в том, что почти ни одно из увиденных мной решений не относится кРазница между потоком байтов и потоком символов, что заставляет меня беспокоиться о том, что я создаю небезопасные строки.

Это лучшее, что я могу придумать, но я не до конца понимаю:

strings -n 1 < /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1

Он совместим с POSIX (за исключением / dev / urandom), но правильно ли я достиг своей цели?Если так, есть ли лучший способ достичь этой цели?Также было бы здорово, если бы был способ создать случайную строку без / dev / urandom, но я думаю, что я об этом мечтаю.

Ответы [ 3 ]

0 голосов
/ 20 мая 2018

Просто используйте awk, что в мандатах POSIX предусмотрена функция rand.

$ cat password.awk
BEGIN {
    srand();
    chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
    s = "";
    for(i=0;i<8;i++) {
        s = s "" substr(chars, int(rand()*62), 1);
    }
    print s
}
$ awk -f password.awk
Cl7A4KVx

(Это почти наверняка можно превратить в код в нечто более короткое; мои навыки awk несколько ограничены.)

Если вам нужно несколько паролей, передайте нужное число в качестве аргумента, чтобы вам не приходилось запускать awk чаще, чем раз в секунду:

BEGIN {
  srand();
  chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
  for(i=0;i<n;i++) {
    s = "";
    for(j=0;j<8;j++) {
      s = s "" substr(chars, int(rand()*62), 1);
    }
    print s
  }
}

Для передачизначение n, запустить как awk -v n=5 -f password.awk, чтобы сгенерировать 5 паролей.

В качестве альтернативы, вы можете передать другое начальное число непосредственно awk:

BEGIN {
  srand(seed);
  chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
  s = "";
  for(i=0;i<8;i++) {
      s = s "" substr(chars, int(rand()*62), 1);
  }
  print s
}

с помощью awk -v seed=$newseed -f password.akw.Обратите внимание, что newseed само по себе должно иметь другое значение каждый раз, но достаточно простой последовательной последовательности семян.

seed=$(date +%s)
awk -v seed=$seed -f password.awk; seed=$((seed + 1))
awk -v seed=$seed -f password.awk; seed=$((seed + 1))
awk -v seed=$seed -f password.awk; seed=$((seed + 1))
# etc
0 голосов
/ 21 мая 2018

Восемь «случайных» буквенно-цифровых символов только с панелью инструментов POSIX?Очень хорошо, вызов!

Давайте начнем с наблюдения, что кодирование Base-64 использует почти только буквенно-цифровые символы (и + и /), а замечательные люди POSIX добавили Base-64 с -m для утилиты uuencode .

Далее, откуда мы получаем (псевдо? Почти?) Случайность из?Заметим еще раз, что текущий список процессов довольно произвольный, особенно если он содержит все процессы в длинном формате, с временем ЦП и еще чем-то подобным.утилита, потому что первая строка вывода ps довольно постоянна, и мы должны были бы искать подходящую строку в выводе с uuencoded (который грязный).

Пока у нас есть

$ ps|cksum|uuencode -m -
begin-base64 644 -
MjUwMDcyMjY3NSAxOTExCg==
====

Выполняя это несколько раз, мы замечаем (или знаем), что первые два символа во второй строке не совсем случайны, так как они содержат длину строки.Таким образом, мы извлекаем 8 символов из позиции 3 в строке 2 с помощью

$ ps|cksum|uuencode -m -|sed -n 's,[+/],0,g; 2s/^..\(........\).*/\1/p'
kzNDkzMj
$ ps|cksum|uuencode -m -|sed -n 's,[+/],0,g; 2s/^..\(........\).*/\1/p'
I0NTcxND

и транспонируем ненужные + и / в 0.Вы почти гарантируете разный результат при каждом вызове, поскольку идентификаторы процессов команд в тройном канале различаются при каждом запуске.

Вуаля!Нет /dev/urandom необходимо: -)

0 голосов
/ 20 мая 2018

Попробуйте это:

head -n 1 /dev/urandom | hexdump | head -n 1 | sed ‘s/0+| //g’ | sed ‘s/\(......\).*/\1/g’
...