Если диск не подключен через USB, рассмотрите возможность использования hdparm
(версия> 9.31) для выполнения ATA Secure Erase диска. Эта команда заставляет микропрограмму накопителя стереть содержимое диска, включая плохие блоки.
Предупреждение: Используйте правильную букву диска - я показал в качестве примера / dev / sdX
- не просто копируйте / вставляйте.
Во-первых, убедитесь, что он понимает команды ATA (большинство дисков, произведенных в последнее десятилетие или более, должны):
$ sudo hdparm -I /dev/sdX
.
# lots of other info here...
.
Security:
Master password revision code = 65534
supported
not enabled
not locked
not frozen
not expired: security count
supported: enhanced erase
202min for SECURITY ERASE UNIT. 202min for ENHANCED SECURITY ERASE UNIT.
Последние две строки отрывка показывают, что он поддерживается.
Поэтому добавьте пароль к диску (очевидно, требование):
$sudo hdparm --user-master u --security-set-pass p /dev/sdX
security_password="p"
и удалите:
$sudo hdparm --user-master u --security-erase p /dev/sdX
security_password="p"
/dev/sdX:
Issuing SECURITY_ERASE command, password="p", user=user
Более подробная информация об этой процедуре доступна здесь .
awk -v n=10 -v seed="$RANDOM" 'BEGIN { srand(seed); for (i=0; i<n; ++i) printf("%.4f\n", rand()) }'
Esto generará n
números aleatorios (diez en el ejemplo )en el rango [0,1 )con cuatro dígitos decimales. Utiliza la función rand()
enawk
(no en el estándar awk
pero implementada por las implementaciones awk
más comunes )que devuelve un valor aleatorio en ese rango. El generador de números aleatorios está sembrado por la variable $RANDOM
del shell.
Cuando un programa awk
solo tiene bloques BEGIN
(y ningún otro bloque de código ), awk
no intentará leer la entrada de su flujo de entrada estándar.
En cualquier sistema OpenBSD (o sistema que tenga la mismajot
utilidad , originalmente en 4.2BSD ), lo siguiente generará 10 números aleatorios como se especifica:
jot -p 4 -r 10 0 1
Usar$(( ( RANDOM % N ) + MIN ))
Reemplace N
con el número MAX y MIN con el número mínimo que desea generar.(N
como MAX es exclusivo, coloque N+1
para tener MAX, MIN inclusive ).
O puede usar $(shuf -i MIN-MAX -n 1)
en su lugar.
deman shuf
:
-i, --input-range=LO-HI
treat each number LO through HI as an input line
-n, --head-count=COUNT
output at most COUNT lines
El -n 1
en shuf
aquí significa generar solo un número aleatorio.
Esto generará números aleatorios entre 0 ~9999 con ceros a la izquierda usandoprintf
(como resultado, el número 1 es exclusivo ).
printf "0.%04d\n" $(( RANDOM % 1000 ))
0.0215
На баш
bc -l <<< "scale=4 ; $((RANDOM % 10000 ))/10000"
где 1/10000
— ваша случайная точность, а 4
— ваша выходная точность
Как указано в другом ответе, существуют и другие утилиты, которые можно использовать для генерации случайных чисел. В этом ответе я ограничиваю свои ресурсы $RANDOM
и несколькими основными арифметическими функциями.
Для чисел с плавающей запятой попробуйте что-то вроде
printf '%s\n' $(echo "scale=8; $RANDOM/32768" | bc )
Это даст вам максимальную точность, потому что $RANDOM
генерирует только числа от 0 до 32767. (включая 32767! )Но я также нарушил правило использования базовых арифметических функций, вызвав bc
.
Но прежде чем двигаться дальше, я хотел бы рассмотреть две проблемы точность и диапазон для чисел с плавающей запятой. После этого я рассмотрю создание диапазона целых чисел (, и если вы можете генерировать целые числа, вы можете позже разделить их, чтобы получить десятичную дробь, если хотите, используя любые утилиты, которые вы предпочитаете для этого.)
Точность
Используя подход $RANDOM/32768
, поскольку $RANDOM
генерирует значения от 0 до 32767, результатом $RANDOM/32768
также будет конечное число значений. Другими словами, это по-прежнему дискретная случайная величина (, и с помощью компьютера вы никогда не сможете избежать этого факта ). Имея это в виду, вы можете достичь некоторой степени точности , используя printf
.
Если вы хотите более тонкое покрытие интервала, вы можете начать думать с основанием 32768. Таким образом, теоретически $RANDOM + $RANDOM*32768
должно дать вам равномерное распределение между 0 и 1 073 741 823. Но я сомневаюсь, что командная строка справится с такой точностью очень хорошо. Несколько моментов, касающихся этого конкретного случая:
$RANDOM + $RANDOM*32768 = $RANDOM * ( 1 + 32768 )
. Два появления $RANDOM
на самом деле являются двумя разными событиями. $RANDOM
, чтобы знать, действительно ли двойной вызов этого метода сгенерирует два независимых случайных события. Диапазон
Рассмотрим просто $RANDOM/32768
. Если вам нужно число в диапазоне, скажем [a,b)
, затем
$RANDOM/32768*(b-a) + a
приведет вас в нужный диапазон.
Генерация целочисленных значений
Во-первых, рассмотрите возможность генерации случайных чисел между [0,b)
, где b
меньше, чем 32768
. Рассмотрим произведение q*b
, где q
— целая часть 32768/b
. Тогда вы можете сгенерировать случайное число от 0 до 32767, но отбросить те, которые больше или равны q*b
. Позвоните на сгенерированный таким образом номер G
. Тогда G
попадет в диапазон от 0 до q*b
, и его распределение будет равномерным. Теперь примените модульную арифметику, чтобы уменьшить это значение до нужного диапазона :
G % b
Обратите внимание, случайным образом генерируется число следующим образом
$RANDOM % b
не создаст равномерного распределения, если только b
не окажется одним из делителей 32768
.
Написание bash-скрипта для этого
Вычисление q*b
как описано выше звучит как боль. Но на самом деле это не так. Вы можете получить его следующим образом:
q*b = 32768 - ( 32768 % b )
В Bash это можно сделать с помощью
$((32768 - $((32768 % b)) ))
Следующий код сгенерирует случайное число в диапазоне 0..b
(, не включаяb
).b=$1
m=$((32768 - $((32768 % $1)) ))
a=$RANDOM
while (( $a > $m ));
do
a=$RANDOM
done
a=$(($a % $1))
printf "$a\n"
Приложение
Технически нет смысла работать с
m=$((32768 - $((32768 % $1)) ))
Следующее сделает то же самое
a=$RANDOM
while (( $a > $1 ));
do
a=$RANDOM
done
printf "$a\n"
Это намного больше работы, но компьютеры работают быстро.
Генерация целого числа в большем диапазоне
Я дам вам разобраться. Необходимо соблюдать осторожность,и в какой-то момент вам придется принять во внимание ограничения памяти компьютера при выполнении арифметических операций.
Последнее примечание
Принятый ответ не будет создавать случайное число от 0 до 1.
Чтобы увидеть это, попробуйте следующее
$ for i in {1..1000}; do echo.$RANDOM; done | awk '{ a += $1 } END { print a }'
Для действительно равномерного распределения по [0,1)
вы должны увидеть среднее значение, близкое к 0.500
.
Но, как вы можете видеть, запустив приведенный выше фрагмент, вместо этого вы получите что-то вроде 314.432
или 322.619
. Поскольку это 1000 чисел, среднее значение равно .322
. Истинное среднее значение для этой последовательности сгенерированных чисел равно.316362
Вы можете получить это истинное среднее значение с помощью скрипта perl
perl -e '{ $i=0;
$s=0;
while ( $i<=32767 )
{
$j = sprintf "%.5f", ".$i";
$j =~ s/^0\.//;
print "$j\n";
$s += $j;
$i++
};
printf "%.5f\n", $s/32767;
}'
Я добавляю сюда целые числа, чтобы помочь вам понять, почему такой подход с использованием .$RANDOM
не делает того, что вы, скорее всего, хотите. Другими словами, подумайте о том, какие целые числа генерируются, а какие вообще отсутствуют. Пропускается довольно большое количество; довольно многие удваиваются.
zsh
имеет rand48()
арифметическую функцию (оболочку стандартной функции erand48()
)в своем zsh/mathfunc
модуле:
zmodload zsh/mathfunc
printf '%.4f\n' $((rand48()))
В то время как $RANDOM
является 15-битным, псевдо -случайным и воспроизводимым, bash
5.1+ имеет более безопасное 32-битное целое число $SRANDOM
, основанное на действительно случайных источниках, где они доступны. Он не поддерживает арифметику с плавающей запятой,но, по крайней мере, вы можете использовать его для заполнения псевдослучайного генератора awk
(, который в противном случае по умолчанию использует очень предсказуемый результатtime()
):
echo "$SRANDOM" | awk '
{
srand($1)
for (i = 0; i < 20; i++)
printf "%.4f\n", rand()
}'
(имейте в виду, что это всего лишь 32 бита энтропии, и awk
выполняет детерминированную псевдо--случайную генерацию на основе этого начального числа)
В системах, где printf оболочки может понимать формат %a
(bash ksh zsh и т. д. )и, следовательно, может выполнять внутреннее изменение базы (hex -> dec)(равномерный в [0,1)
в диапазоне от 0,00003 до 0,99997):
printf '%.5f\n' "$(printf '0x0.%04xp1' $RANDOM)"
Вы даже можете использовать больше цифр, объединив больше вызовов на$RANDOM
(от 0,000000001 до 0,999999999)
printf '%.9f\n' "$(printf '0x0.%08xp2' $(( ($RANDOM<<15) + $RANDOM )))"
Внутренний (для оболочки )алгоритм "$RANDOM" основан на линейном -регистре сдвига с обратной связью (LFSR ). Это не криптографически безопасные генераторы псевдослучайных чисел (CSPRNG ). Лучшим вариантом является использование байтов из устройства /dev/urandom
. Это потребует вызова внешнего восьмеричного или шестнадцатеричного дампа.
$ printf '%.19f\n' "0x0.$(od -N 8 -An -tx1 /dev/urandom | tr -d ' ')"
0.7532810412812978029
$ printf '%.19f\n' "0x0.$(hexdump -n 8 -v -e '"%02x"' /dev/urandom)"
0.9453460825607180595
Очень простое (, но не -единообразное )решение для получения числа с плавающей запятой:
printf '0.%04d\n' $RANDOM
Способ сделать его равномерным в диапазоне [0,1)
(, не включающем 1):
while a=$RANDOM; ((a>29999)); do :; done; printf '0.%04d\n' "$((a%10000))"