IBM Support

Generating Random Numbers Using API Qc3GenPRNs

Troubleshooting


Problem

The API CEERAN0 can be used to generate random numbers using the Qc3GenPRNs API.

Resolving The Problem

On IBM® iSeries™ family of servers, the API CEERAN0 is used to generate random numbers in the (0,1) range; however, in several tests CEERAN0 showed a relatively short period (number of consecutive random numbers generated without repetition): the exact period depends on the initial seed used, but appears to be somewhere in the thousands. This is due to implementation issues in the API. An alternate generator with a much longer period can be implemented using API Qc3GenPRNs which is based on the FIPS 186-1 algorithm. This API is primarily intended for cryptography support but will still work even if this support is not installed. Qc3GenPRNs produces a pseudo-random binary stream whose length is measured in bytes; for applications currently using CEERAN0, Qc3GenPRNs' output has to be normalized to the (0,1) range: this makes the change in generation algorithm transparent to the applications. The following ILE IBM® RPG/400® example illustrates the invocation of Qc3GenPRNs and the normalization technique.

Note: This general approach may be ported to ILE C/C++ but will not work with ILE COBOL. The normalization technique relies on unsigned integers which, as of V5R2, are not supported in ILE COBOL. However, a generator/normalizer module or service program may be coded in ILE RPG or ILE C/C++, then bound to an ILE COBOL program.

*****************************************************************
      *  This program generates pseudo-random floating-point numbers
      *  in the (0,1) range, which are written to a database file.
      *  The program invokes API Qc3GenPRNs to generate the numbers.
      *  Qc3GenPRNs is based on the FIPS 186-1 algorithm, and is
      *  primarily intended for cryptographic use.  However,
      *  applications can be designed to normalize the APIs output
      *  to the (0,1) range; an example of this technique is shown
      *  in the program.
      *  Qc3GenPRNs has a companion API Qc3AddPRNGSeed, which is
      *  used to add seed into the system seed digest.  This
      *  program does not use the latter API, therefore the seed
      *  digest is populated by default using system information.
      *
      *  Compile this program with:
      *
      *  CRTRPGMOD MODULE(member_name)
      *
      *  CRTPGM PGM(module__name) BNDSRVPGM(QC3PRNG)
      *
      *  where QC3PRNG is the service program exporting the two APIs.
      *
      *****************************************************************
      *
      *  Physical file to store the random numbers generated.
      *
     Ffipspf    O    E             DISK
      *****************************************************************
      *
      *  Definitions of standard data types.
      *
     D StdInt          S             10I 0                                      integer
      *
      *  The next 3 data types are explained in more detail in the
      *  documentation for Qc3GenPRNs.
      *
     D StdBinStream    S              8A                                        binary stream
     D StdType         S              1A                                        type
     D StdParity       S              1A                                        parity
      *****************************************************************
      *
      *  Standard error structure definition (see
      *  QSYSINC/QRPGLESRC/QUSEC.
      *
     D QUSEC           DS
     D QUSBPRV                 1      4B 0
     D QUSBAVL                 5      8B 0
     D QUSEI                   9     15
     D QUSERVED               16     16
      *
      *  Provide 100 bytes of storage for the API to return error
      *  information.
      *
     D QUSED01                17    116
      *****************************************************************
      *
      *  Prototype for API Qc3GenPRNs.  See API documentation for
      *  additional details.
      *
     D fips186_1       PR                  EXTPROC('Qc3GenPRNs')
     D parm1                               LIKE(StdBinStream)
     D parm2                               LIKE(StdInt)
     D parm3                               LIKE(StdType)
     D parm4                               LIKE(StdParity)
     D parm5                               LIKE(Qusec)
      *****************************************************************
      *
      *  Data structure ds1 is intended to contain the output from
      *  Qc3GenPRNs.  Two overlaying subfields are defined:  var1a is
      *  of type character, as the API requires; var1u is an unsigned
      *  integer, for later numerical processing.
      *
     D ds1             DS
     D var1a                   1      8A
     D var1u                   1      8U 0
      *
      *  Length of PRN data receiver var1a.
      *
     D var2            S                   LIKE(StdInt)
      *
      *  PRN type.
      *
     D var3            S                   LIKE(StdType)
      *
      *  PRN Parity.
      *
     D var4            S                   LIKE(StdParity)
      *
      *  Variable to contain divisor for normalization.
      *  var6a is needed for initialization (see below).
      *  var6u is used for numerical processing.
      *
     D ds6             DS
     D var6a                   1      8A
     D var6u                   1      8U 0
      *
      *  Counter for loop to generate random numbers.
      *
     D counter         S                   LIKE(StdInt)
      *
      *  Number of iterations/random numbers to generate.
      *
     D n               C                   CONST(100)
      *****************************************************************
      *
      *  Initialize divisor to largest 8-byte unsigned integer
      *  ((2 ** 64) - 1).
      *  This is hexadecimal
      *  FFFFFFFFFFFFFFFF
      *  or decimal
      *  18446744073709551615
      *
     C                   eval      var6a = X'FFFFFFFFFFFFFFFF'
      *
      *  Provide the API with 100 bytes to return error data in case
      *  of failure.
      *
     C                   eval      QUSBPRV = 100
      *
      *  Initialize bytes available. Qc3GenPRNs will change this to a
      *  a non-zero value in case of failure.
      *
     C                   eval      QUSBAVL =   0
      *
      *  Set length of PRN data receiver.
      *
     C                   eval      var2 = %len(var1a)
      *
      *  Set PRN type to '0' (generate real pseudorandom numbers).
      *
     C                   eval      var3 = '0'
      *
      *  Set PRN parity to '0' (do not set parity in the binary stream).
      *
     C                   eval      var4 = '0'
      *
      *  Generate n random numbers.
      *
     C                   for       counter = 1 by 1 to n
      *
      *  Invoke API for next random number.
      *
     C                   callp     fips186_1(var1a:var2:var3:var4:QUSEC)
      *
      *  Normalize the API's output to the (0,1) range.  The output is
      *  treated as an 8-byte unsigned integer; dividing it by
      *  ((2 ** 64) - 1) reduces it to the desired range.
      *  The normalized value is assigned to the appropriate field in
      *  the file buffer.
      *
     C                   eval      fipsfld = var1u / var6u
      *
      *  Write random number to the output file.
      *
     C                   write     fipsrec
     C                   endfor
      *
      *  End program.
      *
     C                   eval      *inlr = *on
      *****************************************************************


The file fipspf is defined with the following DDS:


 * COMPILE THIS FILE WITH SIZE(*NOMAX)                
     A          R FIPSREC                                  
     A            FIPSFLD       17F 7       FLTPCN(*DOUBLE)

[{"Type":"MASTER","Line of Business":{"code":"LOB57","label":"Power"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SWG60","label":"IBM i"},"Platform":[{"code":"PF012","label":"IBM i"}],"Version":"7.1.0"}]

Historical Number

28281720

Document Information

More support for:
IBM i

Software version:
7.1.0

Operating system(s):
IBM i

Document number:
640229

Modified date:
18 December 2019

UID

nas8N1016809

Manage My Notification Subscriptions