9.6. $RANDOM: генерация псевдослучайных целых чисел
$RANDOM — внутренняя функция Bash (не константа), которая возвращает псевдослучайные целые числа в диапазоне 0 — 32767. Функция $RANDOM не должна использоваться для генераци ключей шифрования.
Пример 9-23. Генерация случайных чисел
Пример 9-24. Выбор случайной карты из колоды
Jipe подсказал еще один способ генерации случайных чисел из заданного диапазона.
Насколько случайны числа, возвращаемые функцией $RANDOM? Лучший способ оценить «случайность» генерируемых чисел — это написать сценарий, который будет имитировать бросание игрального кубика достаточно большое число раз, а затем выведет количество выпадений каждой из граней.
Пример 9-25. Имитация бросания кубика с помощью RANDOM
Как видно из последнего примера, неплохо было бы производить переустановку начального числа генератора случайных чисел RANDOM перед тем, как начать работу с ним. Если используется одно и то же начальное число, то генератор RANDOM будет выдавать одну и ту же последовательность чисел. (Это совпадает с поведением функции random() в языке C.)
Пример 9-26. Переустановка RANDOM
Системный генератор /dev/urandom дает последовательность псевдослучайных чисел с более равномерным распределением, чем $RANDOM. Команда dd if=/dev/urandom of=targetfile bs=1 count=XX создает файл, содержащий последовательность псевдослучайных чисел. Однако, эти числа требуют дополнительной обработки, например с помощью команды od (этот прием используется в примере выше) или dd (см. Пример 12-42).
Есть и другие способы генерации псевдослучайных последовательностей в сценариях. Awk имеет для этого достаточно удобные средства.
Пример 9-27. Получение псевдослучайных чисел с помощью awk
Источник
1. The meaning of generating random numbers and strings
1. Use the system’s $RANDOM variable
(CentOS, Ubuntu, MacOS all support)
The range of $RANDOM is [0, 32767], only 5 digits are random
Randomly generate 10 5-digit numbers:
Operation result: (randomly generated may not have 5 digits, this method is not recommended)
2. Use date +%s%N
(CentOS, Ubuntu support, MacOS does not support nanosecond +%N) Principle: Get random numbers through Linux/Unix timestamp
If you use the timestamp date +%s as a random number, the data for the same second is the same. Basically cannot meet the requirements when doing loop processing multithreading
If the nanosecond value date +%N is used as a random number, the accuracy reaches 1/100 million, which is quite accurate. In a multi-cpu high-concurrency loop, the same result is difficult to appear in the same second, but there will be repeated collision The possibility of
If you use timestamp + nanosecond value date +%N%s as a combined random number (10+9=19 digits), it is perfect, and the probability of repetition is greatly reduced, but note: MacOS does not support nanosecond values. Not universal
3. Use /dev/random and /dev/urandom random files
(CentOS, Ubuntu, MacOS are all supported, recommended) /dev/random is a blocking random number generator, and reading sometimes requires waiting. Stores real-time data of the current operating environment of the system, such as CPU, memory, voltage, physical signals, etc.
/dev/urandom is a non-blocking random number generator, read operations will not cause blocking.
/dev/random and /dev/urandom store garbled characters, in fact they store real-time data through binary data
Open /dev/random and /dev/urandom files, head is recommended, cat command is not recommended, because the file is very large and garbled, only the first few lines of file content are changed
The cksum command is used to read the content of the file and generate unique integer data. Only if the content of the file is unchanged, the generated result will not change. Similar to the php crc function, it generally checks whether the file has been tampered with
The principle of generating random numbers is: intercept part of the content of the file, do the calculation of the content, and take the first value
4. Use linux uuid
UUID (Universally Unique Identifier), the format contains 32 hexadecimal digits, divided into 5 segments by the’-‘ connection number
UUID quantity: The theoretical total is 216 x 8=2128, which is approximately equal to 3.4 x 1038. In other words, if 1 trillion UUIDs are generated every nanosecond, it will take 10 billion years to use up all UUIDs.
UUID purpose: It is to allow all elements in the distributed system to have unique identification information, without the need to specify identification information through the central control terminal. In this way, everyone can create UUIDs that do not conflict with others. In this case, there is no need to consider the problem of duplication of names when the database is created. It makes the uuid code generated by any computer on the network unique in the entire server network on the Internet. Its original information will be added to the hardware, time, current operating information of the machine and so on.
UUID format: Contains 32 hexadecimal digits, divided into five segments by the «-» connection number, in the form of 32 characters of 8-4-4-4-12. Example; 550e8400-e29b-41d4-a716-446655440000, so:
Similar to uuid, there is also a guid (globally unique identifier) code, which is supported by Microsoft, and they are generated by the operating system kernel.
5. Use openssl rand
openssl rand is used to generate random characters of specified length bytes
Among them, the parameter -base64 or -hex performs base64 encoding on the random string or displays it in hex format
Combine cksum to generate integers and md5sum to generate strings, which can generate random integers or strings (only lowercase letters and numbers) For example:
6. Generate random numbers from custom arrays
A custom array is used to generate a string of numbers and letters with a specific length (up to 18 digits for integers). The elements in the string are taken from a custom pool.
7. Generate a random string
All the methods that can generate random integers described above can generate random strings. The principle is to perform md5sum calculation on random integers. Example: Generate 10-digit random string
Three, application examples
1. Randomly generate ports
Randomly generate port numbers ranging from 1025 to 65536 (commonly used in CentOS, Ubuntu, MacOS), and support excluding any added port numbers The random number applied is Method 3. Use /dev/random and /dev/urandom random files
2. Randomly generate 10-digit password
Randomly generate a password string of length 10 (commonly used in CentOS, Ubuntu, MacOS) Example code:
Four, summary
The pseudo data sources of random, urandom, uuid, openssl rand, and custom arrays ($RANDOM is used) to generate random codes are all related to the /dev/random device, but they are presented differently.
The random number generated by date has little to do with the random device /dev/random of the Linux system, but the system time also affects the /dev/random device, and the two are not absolutely unrelated.
All methods that can generate random integers can generate random strings. The principle is to perform md5sum calculation on random integers.
Источник
Linux Shell Generates Random Numbers and Random Strings
Random numbers are often used in daily life. They are used in a wide range of scenarios, such as lottery tickets, dice throwing, lottery drawing, annual lottery, etc.
How to generate random numbers under shell? The Mipu blog wrote this article specially to summarize various methods of generating random numbers under Linux shell.
The original text of this article is from Mip Blog: Linux Shell Generates Random Numbers and Random Strings
The computer produces only “pseudo-random numbers” and does not produce absolute random numbers (an ideal random number). In fact, pseudo-random number and ideal random number are relative concepts, such as pseudo-random number can not be repeated in 10 trillion billion years. Is it an ideal random number?
Pseudo-random numbers do not necessarily remain unique when they are reproduced in large quantities, but a good pseudo-random generation algorithm will produce a very long non-repetitive sequence, such as UUID.(Universal Unique Identification Code) It will be used up in 10 billion years.
1. Use the $RANDOM variable of the system(CentOS, Ubuntu, MacOS all support, but only 5-digit random)
The range of $RANDOM is [0, 32767]
Example:Use the for loop to verify:
If you need to generate more than 32767 random numbers, you can use the following methods to achieve (defective)
Example: Generate 40,000,000-50,000,000 random numbers, but the last five digits change randomly. The realization principle is defective.
Here, we can also generate random numbers through awk, the maximum of which is 6-bit random numbers, which are time-dependent, while the random numbers are the same when the system time is consistent, and there is no good randomness of $RANDOM.
2. Use date +% s% N(CentOS, Ubuntu support, MacOS does not support nanoseconds +% N)
Getting random numbers through Linux / Unix timestamps
# date +% S # Get seconds, 2 digits 43 # Date +% s Gets the timestamp, 10 digits, seconds from 1970-01-01 00:00:00 to the current interval 1548739004 # date +% N Gets nanosecond value, 9 digits, CentOS, Ubuntu support, but MacOS does not support 468529240
If the time stamp date +% s is used as a random number, the data for the same second is the same. When multithreading is processed in a loop, it can hardly meet the requirement.
If we use the nanosecond value of date +% N as random number, the precision reaches one billionth, which is quite accurate. In the high concurrent cycle of multi-cpu, it is very difficult to achieve the same result in the same second, but there will also be the possibility of repeated collisions.
If we use timestamp + nanosecond value date +% N% s as combined random number (10 + 9 = 19 digits), it will be perfect, the probability of repetition will be greatly reduced, but note: MacOS system does not support nanosecond value, it is not universal.
Example:Generate 40,000,000-50,000,000 random numbers
As can be seen from the above results, when taking a large numerical range, the high positions may be the same, because date +% N% s is obtained in seconds + nanoseconds, and the high positions of time have sequence bits, which may be the same.
Then, some students asked if they could exchange the number of seconds of date +% s% N with the number of nanoseconds. The answer is not possible. The reason is that the first place of nanoseconds may be 0, and the interception from the first place may be 09641524615487432. The shell will prompt error s: value too big for base (error token is “09641524615487432”).
Improvement 1: IntermodulationDate +% N% s (still not good):
Since the first bit can’t be zero, can’t we intercept from the second and third bit of nanoseconds? The answer is no, because every bit of nanoseconds can be zero. After all, nanoseconds are 9 digits (3 digits in milliseconds, 6 digits in microseconds, 9 digits in nanoseconds) nanoseconds themselves are after seconds, so each of the 9 digits in nanoseconds can be 0. In addition, nanoseconds are in high digits and seconds are in high digits. Low, intercepting large values may lead to different high values, but the same low values, because the value of seconds changes very slowly. In conclusion, the method of interchange is not feasible, and may lead to new problems. Therefore, honestly use date +% s% N format.
The improved method 2:Direct use of date +% s% N 19 digits (feasible)
Do not intercept date +% s% N | cut – C1 – 17, make full use of the rapid changes in nanoseconds before redundancy
3. Use / dev / random and / dev / urandom random files(CentOS, Ubuntu, MacOS all support, recommend)
/ dev/random is a blocked random number generator. Reading sometimes requires waiting. Store real-time data of the system’s current operating environment, such as CPU, memory, voltage, physical signals, etc.
/ dev/urandom is a non-blocking random number generator, and the read operation will not cause blocking.
/ dev / random and / dev / urandom store scrambled code, but in fact they store real-time data through binary data
Open / dev / random and / dev / urandom files, recommend head, not cat command, because the file is very large and scrambled, just need to get the first few lines of file content will change.
Using cksum command, it reads the file content and generates unique integer data. Only if the file content remains unchanged, the result will not change. Similar to PHP CRC function, it generally checks whether the file is tampered with or not.
The principle of generating random number is to intercept part of the file, calculate the content and take the first value.
Example:Use / dev / urandom to generate random numbers between 40,000,000 and 50,000,000, and use / dev / urandom to avoid blocking.
It can be seen that the random numbers generated by random files are basically totally random and are generally used in CentOS, Ubuntu and MacOS.
4. Using Linux UUID(CentOS, Ubuntu support, MacOS support)
UUID (Universal Unique Identifier), which contains 32 hexadecimal digits, is divided into 5 segments by’-‘connection number.
32 characters in 8-4-4-4-4-12 format, e.g. 07e73165-1196-4194-98bb-a3bf7c96e34a
UUID quantityThe theoretical total is 216 x 8 = 2128, which is about 3.4 x 1038. That is to say, if 1 trillion UUIDs are generated per nanosecond, it will take 10 billion years to run out of all UUIDs.
UUID purposeIt allows all elements in distributed systems to have unique identification information without the need to specify the identification information through the central control terminal. In this way, everyone can create UUIDs that do not conflict with others. In this case, the duplication of names at the time of database creation is not considered. It will make the UUID code generated by any computer in the network unique in the whole server network of the Internet. Its original information will be added to hardware, time, current machine operation information and so on.
UUID format:It contains 32 16-digit digits and is divided into five segments by the “-” connection number in the form of 32 characters of 8-4-4-4-12. Example: 550e8400-e29b-41d4-a716-446655440000, so:
Similar to uuid, there is also a guid(guid) Codes, which are supported by Microsoft, are generated by the operating system kernel.
Example:Using Linux UUID to generate random numbers between 40,000,000 and 50,000,000
5. Use OpenSSL Rand(CentOS, Ubuntu support, MacOS support, need to install openssl, recommended)
Openssl Rand is used to generate random characters of specified length bytes
The parameter – Base64 or – hex encodes or displays random strings in hex format
Combining cksum to produce integers and md5sum to produce strings can generate random integers or strings (only lowercase letters and numbers)
Example:Using OpenSSL Rand to generate random numbers between 40,000,000 and 50,000,000
6. Generating Random Numbers from Custom Arrays
Customize an array to generate a string of numbers and letters of a specified length (up to 18 bits of integers). The elements in the string are taken from a custom pool.
Array= (0 1 2 3 4 5 6 7 8 9) Customize an array of numbers
Num=$ < array [*]>Gets the length of the array (number of elements)
Randnum=$ Randnum randomly selects an element from the array to form a new length array using the default $RANDOM random number of Linux system.
Example:Custom arrays generate random numbers between 40,000,000 and 50,000,000 (annotations are a bit ugly, but very helpful in understanding code hacks)
7. Generating Random Strings
All the methods mentioned above can generate random integers. They can generate random strings. The principle is to calculate random integers by md5sum.
Example:Generate 10-bit random strings
# Using date to generate random strings date +%s%N | md5sum | head -c 10
# Using / dev / urandom to generate random strings cat /dev/urandom | head -n 10 | md5sum | head -c 10
Random Number Application 1
Random generation of port numbers ranges from 1025 to 65536 (commonly used in CentOS, Ubuntu, MacOS), and supports the exclusion of arbitrarily added port numbers.
The random number applied isMethod 3. Use / dev / random and / dev / urandom random files
Application code:
Random Number Application II
Random generation of password strings with length of 10 (for CentOS, Ubuntu, MacOS)
The random number applied isMethod 1: Use the $RANDOM variable of the system
Application code:
Random Number Application III
Statistics of the number of dice throws, 6,000 throws, 1-6 (commonly used in CentOS, Ubuntu, MacOS)
The random number applied isMethod 1: Use the $RANDOM variable of the system
Application code:
summary
Random, urandom, uuid, OpenSSL rand, and custom arrays (using $RANDOM) generate pseudo-data sources for random codes, all of which are related to / dev / random devices, except that they are presented differently.
The random number generated by date date has little to do with the random device / dev / random of Linux system, but the system time also affects the device / dev / random, which is not absolutely unrelated.
All methods that can generate random integers can generate random strings. The principle is to calculate random integers by md5sum.
Finally, complete shell code is attached to facilitate enthusiasts’research and debugging.