Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Minor edits; almost reviewed (waiting to hear about deprecated rand wording)

A

...

pseudorandom

...

number

...

generator

...

(PRNG)

...

is

...

a

...

deterministic

...

algorithm

...

capable

...

of

...

generating

...

sequences

...

of

...

numbers

...

that

...

approximate

...

the

...

properties

...

of

...

random

...

numbers.

...

Each

...

sequence

...

is

...

completely

...

determined

...

by

...

the

...

initial

...

state

...

of

...

the

...

PRNG

...

and

...

the

...

algorithm

...

for

...

changing

...

the

...

state.

...

Most

...

PRNGs

...

make

...

it

...

possible

...

to

...

set

...

the

...

initial

...

state,

...

also called

...

the

...

seed

...

state. Setting

...

the

...

initial

...

state

...

is

...

called seeding

...

the

...

PRNG.

Calling a PRNG in the same initial state, either without seeding it explicitly or by seeding it with the same value, results in generating the same sequence of random numbers in different runs of the program.

...

This noncompliant code example generates a sequence of 10 pseudorandom numbers using the rand() function. When rand() is not seeded, it uses uses 1 as a default seed. No matter how many times this code is executed, it always produces the same sequence.

Code Block
bgColor#FFCCCC
langc
#include <stdio.h>
#include <stdlib.h>
 
void func(void) {
  for (int i = 0; i < 10; ++i) {
    printf("%d, ", rand()); /* Always generates the same sequence */ 
    printf("%d, ", rand());
  }
}
output:
1st run: 41, 18467, 6334, 26500, 19169, 15724, 11478, 29358, 26962, 24464,
2nd run: 41, 18467, 6334, 26500, 19169, 15724, 11478, 29358, 26962, 24464,
...
nth run: 41, 18467, 6334, 26500, 19169, 15724, 11478, 29358, 26962, 24464,

...

Code Block
bgColor#FFCCCC
langc
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
void func(void) {
  srand(time(NULL)); /* Create seed based on current time */
  for (int i = 0; i < 10; ++i) {
    printf("%d, ", rand()); /* Generates different sequences at different runs */
    printf("%d, ", rand());
  }
}
output:
1st run: 25121, 15571, 29839, 2454, 6844, 10186, 27534, 6693, 12456, 5756,
2nd run: 25134, 25796, 2992, 403, 15334, 25893, 7216, 27752, 12966, 13931,
3rd run: 25503, 27950, 22795, 32582, 1233, 10862, 31243, 24650, 11000, 7328, 

...

Code Block
bgColor#FFCCCC
langc
#include <stdio.h>
#include <stdlib.h>
 
void func(void) {
  for (int i = 0; i < 10; ++i) {
    printf("%ld, ", random()); /* Always generates the same sequence */
    printf("%ld, ", random());
  }
}
output:
1st run: 1804289383, 846930886, 1681692777, 1714636915, 1957747793, 424238335, 719885386, 1649760492, 596516649, 1189641421,
2nd run: 1804289383, 846930886, 1681692777, 1714636915, 1957747793, 424238335, 719885386, 1649760492, 596516649, 1189641421,
...
nth run: 1804289383, 846930886, 1681692777, 1714636915, 1957747793, 424238335, 719885386, 1649760492, 596516649, 1189641421, 

...

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
void func(void) {
  srandom(time(NULL)); /* Create seed based on current time counted as seconds
     from 01/01/1970 */
  srandom(time(NULL));
  for (int i = 0; i < 10; ++i) {
    printf("%ld, ", random()); /* Generates different sequences at different runs */
    printf("%ld, ", random());
  }
}
output:
1st run: 198682410, 2076262355, 910374899, 428635843, 2084827500, 1558698420, 4459146, 733695321, 2044378618, 1649046624,
2nd run: 1127071427, 252907983, 1358798372, 2101446505, 1514711759, 229790273, 954268511, 1116446419, 368192457, 1297948050,
3rd run: 2052868434, 1645663878, 731874735, 1624006793, 938447420, 1046134947, 1901136083, 418123888, 836428296, 2017467418, 

...

Code Block
bgColor#ccccff
langc
#include <Windows.h>
#include <wincrypt.h>
#include <stdio.h>
 
void func(void) {
  HCRYPTPROV hCryptProv;
  long rand_buf;
  /* An example of instantiating the CSP */
  if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
    printf("CryptAcquireContext succeeded.\n");
  } else {
    printf("Error during CryptAcquireContext!\n");
  }

  for (int i = 0; i < 10; ++i) {
    if (!CryptGenRandom(hCryptProv, sizeof(rand_buf), (BYTE *)&rand_buf)) {
      printf("Error\n");
    } else {
      printf("%ld, ", rand_buf.li);
    }
  }
}
output:
1st run: -1597837311, 906130682, -1308031886, 1048837407, -931041900, -658114613, -1709220953, -1019697289, 1802206541, 406505841,
2nd run: 885904119, -687379556, -1782296854, 1443701916, -624291047, 2049692692, -990451563, -142307804, 1257079211, 897185104,
3rd run: 190598304, -1537409464, 1594174739, -424401916, -1975153474, 826912927, 1705549595, -1515331215, 474951399, 1982500583, 

...

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MSC32-C

mediumMedium

likelyLikely

lowLow

P18

L1

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

...