News:

;) This forum is the property of Proton software developers

Main Menu

Creating a unique random / seed number

Started by Fanie, Oct 21, 2025, 09:14 AM

Previous topic - Next topic

Fanie

I was looking at creating a unique number or value at random.
In the manual it says that every pic will repeat the same sequence when using Random or Seed.

To generate a truly unique value could be very easy.

If you have a simple counter inc variable - byte, word... in the main loop and or other parts of the code..

Then when you determine the random or seed number you can use this count at the moment you need the value.
So from power up this value will increment and roll over to 0 and start count up again.

Some form of human interaction, a button pressed, exterior interrupt... is required and this time to interaction should provide a true random number.  It can also be as simple as a jumper or temporary connection.

The time before the counter is accessed at exactly the same interval is highly unlikely.

You can save the random number, or continue to read the next random number from the variable.

Is there an easier or better way to do this ?

charliecoutas

I do this in one of the exhibits at the museum Fanie. I also save the result in EEPROM when I know there will be a power down, and reload it on the next power up.

Les showed us a way of generating random noise with a short length of wire on a PIC input, then ADCing the resulting random noise. This is probably a better way because it doesn't rely on human interaction. I'm sure when he sees this he'll add some of his usual wisdom.

Charlie

top204

#2
Many thanks for your kind words Charlie, and as stated, creating a 'true' random number is very straightforward, and can be accomplished very simply with an open ADC channel, or better still, a noisy biased transistor or diode attached to the ADC input.

Below is a set of procedures I used in the Game of Life simulator for the 16x16 matrix of WS2812B LEDs on a PIC18F26K22 device, and it creates 'true' random integer values between 0 to 65535:

'---------------------------------------------------------------------------------------------
' Create a random bit from an open ADC channel (AN0)
' Input     : None
' Output    : WREG holds the random bit value. i.e. 0 or 1
' Notes     : Make sure that no connection is made to the ADC channel being used
'           : The ADC pin is altered to output low, then high, then made an input, to enhance the noise it picks up.
'
Proc Random_CreateRawBit(), WREG
    PinLow PORTA.0                                                              ' Pull the ADC pin low
    PinSet PORTA.0                                                              ' Set the ADC pin high
    PinInput PORTA.0                                                            ' Make the ADC pin an input
    Result = ADIn(0)                                                            ' Return the ADC value from channel AN0
EndProc

'---------------------------------------------------------------------------------------------
' Return an unsigned 16-bit integer random value
' Input     : pMax holds the maximum value to return
' Output    : Returns the random value between 0 to pMax
' Notes     : Uses the random bit generator, and rotates the bits into a 16-bit value
'
Proc Random_Get(pMax As Word), Word
    Dim bBits As Byte                                                           ' Holds the bits to rotate loop count

    If pMax = 0 Then ExitProc                                                   ' Trap a maximum of 0
    For bBits = 15 DownTo 0                                                     ' Create a loop to build up the random bits
        STATUSbits_C = Random_CreateRawBit()                                    ' Place a random bit into the Carry flag
        Rol Result                                                              ' Rotate the Carry bit into the Result variable
    Next
    Result = Result // pMax                                                     ' Get the maximum value for the return
EndProc

'---------------------------------------------------------------------------------------------
' Initialise the ADC for analogue pin AN0
' Input     : None
' Output    : None
' Notes     : For a PIC18F26K22 device
'           : Make sure pin AN0 is left floating for random values to be read by it
'
Proc ADC_Init()
    ADCON0 = %00000000
    ADCON1 = %00000000
    ADCON2 = %10000111                                                          ' Set for right justification and FRC for the ADC
    ANSELA = %00000001                                                          ' Set pin AN0 as analogue
EndProc

The mechanism can be altered for testing using whitening, or lowering the +VREF threshold of the ADC etc, but as it stands, it produces excellent 'true' random values with the ADC input just left floating with a little piece of wire attached to it.

It works by using the ADC to create floating voltage readings from the noisy atmosphere, and then using the LSB (Least Significant Bit) of it as a bit for the final random value, by taking multiple readings, and rotating them in the final output. So for an 8-bit random value, the ADC will be read, and the floating LSB will be rotated 8 times into an integer variable, and for a 16-bit random value, the ADC will read, and the floating LSB will be rotated 16 times into an integer variable etc...

The same method can be used for floating point random values, but will require more manipulation for the Floating Point mechanism, and should produce a value between 0.0 to 1.0, which can then be multiplied with a larger value to give a random value of any size.

Regards
Les

top204

#3
I have just adapted my earlier really random library to show the floating ADC pin mechanism working on PIC18FxxK22 devices, with four demo programs.

The "really_random.inc" library code listing is shown below:

$ifndef _really_random_inc_
$define _really_random_inc_
'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Produce true random values from an open ADC channel on the device.
' Uses the AN0 ADC channel to create a random bit, then uses the bit to build random bytes or words.
' Peripheral setups are for a PIC18F26K22 device, operating at 64MHz with its internal oscillator.
'
' Written by Les Johnson for the Positron8 BASIC compiler.
' https://sites.google.com/view/rosetta-tech/home
'
'----------------------------------------------------------------------------------------
' Create a random bit from an open AN0 ADC channel
' Input     : None
' Output    : Returns the random bit value
' Notes     : Make sure that no connection is made to the ADC channel being used
'           : Also make sure it is not near a continuous signal device, such as a USB keyboard, AC light bulb etc...
'           : A noisy transistor or diode circuit would work well connected to the ADC's input
'
Proc Rand_CreateRawBit(), Bit
    ANSELA.0 = 1                                    ' Set RA0 (AN0) to analogue
    PinLow PORTA.0                                  ' Pull the ADC pin low
    PinSet PORTA.0                                  ' Set the ADC pin high
    PinInput PORTA.0                                ' Make the ADC pin an input
    Result = ADIn(0)                                ' Return bit-0 of the the ADC value
EndProc

'--------------------------------------------------------------------------
' Create a random 16-bit integer value between minimum and maximum values
' Input     : pMin holds the minimum random value to return
'           : pMax holds the maximum random value to return
' Output    : Returns a random value
' Notes     : Maximum 16-bit return (0 to 65535)
'           : Uses the equation (hRand16() // (pMax - pMin)) + pMin
'
Proc Rand16(pMin As Word, pMax As Word), Word
Global Dim Rand_bIndex As Byte Shared

    If pMax < 65535 Then
        pMax = pMax + 1
    EndIf
    For Rand_bIndex = 15 DownTo 0                   ' Create a loop to make a random word
        STATUSbits_C = Rand_CreateRawBit()          ' Get a random bit into the Carry bit
        Rol Result                                  ' Rotate the Carry bit into the Result variable
    Next
    pMax = pMax - pMin
    Result = Result // pMax
    If pMin <> 0 Then
        Result = Result + pMin
    EndIf
EndProc

'--------------------------------------------------------------------------
' Create a random 8-bit integer value between minimum and maximum values
' Input     : pMin holds the minimum random value to return
'           : pMax holds the maximum random value to return
' Output    : Returns a random value
' Notes     : Maximum 8-bit return (0 to 255)
'           : Uses the equation (hRand8() // (pMax - pMin)) + pMin
'
Proc Rand8(pMin As Byte, pMax As Byte), Byte
Global Dim Rand_bIndex As Byte Shared

    If pMax < 255 Then
        pMax = pMax + 1
    EndIf
    For Rand_bIndex = 7 DownTo 0                    ' Create a loop to make a random byte
        STATUSbits_C = Rand_CreateRawBit()          ' Get a random bit into the Carry bit
        Rol Result                                  ' Rotate the Carry bit into the Result variable
    Next
    pMax = pMax - pMin
    Result = Result // pMax
    Result = Result + pMin
EndProc

'--------------------------------------------------------------------------------
' Create a floating point random number between 0 and 1
' Input     : None
' Output    : A floating point value of 0 to 1
' Notes     : None
'
Proc fRand(), Float
Global Dim Rand_bIndex As Byte Shared

    For Rand_bIndex = 15 DownTo 0                   ' Create a loop for the 16-bits
        STATUSbits_C = Rand_CreateRawBit()          ' Get a random bit into the Carry bit
        Rol Result.Word                             ' Rotate the Carry bit into the Result variable cast as a word type
    Next
    Result = Result.Word / 65536.0
EndProc

$endif      ' _really_random_inc_

And the lottery predicor demo is listed below:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' This demo is a lottery number predictor using the real random library.
' Uses AN0 as the ADC channel for the random bit generator, but this can be changed within the library code.
' Peripheral setups are for a PIC18F26K22 device, operating at 64MHz with its internal oscillator.
'
' Written by Les Johnson for the Positron8 BASIC compiler.
' https://sites.google.com/view/rosetta-tech/home
'
    Device = 18F26K22                                               ' Tell the compiler what device the code is being compiled for
    Declare Xtal = 64                                               ' Tell the compiler what frequency the device is operating at (in MHz)
    Declare Auto_Heap_Strings = On                                  ' Make all Strings "Heap" types, so they always get placed after standard variables
    Declare Auto_Variable_Bank_Cross = On                           ' Make sure all multi-byte variables remain within a single RAM bank
'
' Setup the USART1 peripheral
'
    Declare Hserial_Baud = 9600                                     ' Set the Baud rate for USART1
    Declare HRSOut_Pin = PORTC.6                                    ' Choose the TX pin for USART1
    Declare HRSIn_Pin = PORTC.7                                     ' Choose the RX pin for USART1
   
    Include "Really_Random.inc"                                     ' Load the true Random library into the program
'
' Create some globalvariables for the demo
'
    Dim wRandomValue      As Word                                   ' Holds a 16-bit random value
    Dim bRandomValue      As Byte                                   ' Holds an 8-bit random value
    Dim bPredictLoop      As Byte                                   ' Holds the loop for the number predictions
    Dim bWinningNumbers[7] As Byte                                  ' Holds the seven predicted random numbers

'---------------------------------------------------------
' The main program loop starts here
' Press a key on the serial terminal to start the prediction of 7 numbers
' Each number will be displayed on the serial terminal
'
Main:
    Setup()                                                         ' Setup the program and any peripherals

    Clear bWinningNumbers                                           ' Clear the array that holds the winning numbers
    HRSOutLn "     Lottery Predictor!"
    DelayMS Rand16(200, 1000)                                       ' Delay a random amount of time before starting

    HRSOutLn "Press a key to start the prediction"
    WREG = HRSIn                                                    ' Wait for a serial character before continuing
    DelayMS Rand16(400, 1000)                                       ' Pause for drama
    HRSOut 13
    For bPredictLoop = 0 To 6                                       ' Create a loop for 7 numbers
        Repeat                                                      ' Create loop until the random number has not already been chosen
            bRandomValue = Rand8(1, 49)                             ' Get a random number between 1 and 49 into bRandomValue
        Until CheckForDuplicate(bRandomValue) = 0                   ' Keep getting a random value until not duplicated
        bWinningNumbers[bPredictLoop] = bRandomValue                ' Load the array with the predicted number

        If bPredictLoop = 6 Then                                    ' Is this the bonus ball?
            HRSOut "\rAnd the Bonus Number is: "
            DelayMS 5000                                            ' Yes. So. pause for drama
            HRSOutLn "(", Dec bWinningNumbers[bPredictLoop], ")"
        Else
            HRSOutLn "The Winning number is:   (",                  ' \
                      Dec bWinningNumbers[bPredictLoop], ")"        ' / Display each number predicted
        EndIf
        DelayMS Rand16(1000, 1500)                                  ' Pause for drama
    Next
    HRSOutLn "\r\rGood Luck!"

'----------------------------------------------------------------------------------------
' Make sure any numbers predicted are not duplicated
' Input     : Array bWinningNumbers holds the values already created
' Output    : Returns the value 1 if a duplicate value is found, else returns the value 0
' Notes     : None
'
Proc CheckForDuplicate(pValue As Byte), Bit
    Dim bIndex As Byte

    Result = 0                                                          ' Default to no duplicate found
    For bIndex = 0 To 6                                                 ' Scan all 7 elements of the array
        If pValue = bWinningNumbers[bIndex] Then                        ' Is the number already in the array?
            Result = 1                                                  ' Yes. So exit with a result of 1
            ExitProc                                                    ' Exit the procedure
        EndIf
    Next
EndProc

'---------------------------------------------------------------------------------------------
' Setup the program and any peripherals
' Input     : None
' Output    : None
' Notes     : None
'
Proc Setup()
    Osc_64MHz()                                                         ' Set the device to 64MHz operation using its internal oscillator
    ADC_Init()                                                          ' Initialise the ADC for analogue pin AN0
EndProc

'---------------------------------------------------------------------------------------------
' Initialise the ADC for analogue pin AN0
' Input     : None
' Output    : None
' Notes     : For a PIC18F26K22 device
'           : Make sure pin AN0 is left floating for random values to be read by it
'
Proc ADC_Init()
    ADCON0 = %00000000
    ADCON1 = %00000000
    ADCON2 = %10000111                                                  ' Set for right justification and FRC for the ADC
    ANSELA = %00000001                                                  ' Set pin AN0 as analogue
EndProc

'---------------------------------------------------------------------------------------------
' Set the PIC18F26K22 device to 64MHz operation using its internal oscillator
' Input     : None
' Output    : None
' Notes     : None
'
Proc Osc_64MHz()
    OSCCON  = $70
    OSCCON2 = $04
    OSCTUNE = $40
    DelayMS 100
EndProc

'---------------------------------------------------------------------------------------------
' Setup the fuses to use the internal oscillator on a PIC18F26K22 device.
' OSC pins RA6 and RA7 are general purpose I/O.
'
Config_Start
    FOSC     = INTIO67                                                  ' Internal oscillator
    PRICLKEN = Off                                                      ' Primary clock disabled
    MCLRE    = EXTMCLR                                                  ' MCLR pin enabled
    WDTEN    = Off                                                      ' Watchdog Timer disabled
    Debug    = Off                                                      ' Background debugger disabled. RB6 and RB7 configured as general purpose I/O pins
    PLLCFG   = Off                                                      ' Oscillator used directly
    XINST    = Off                                                      ' Extra mnemonics disabled
    FCMEN    = Off                                                      ' Fail-Safe Clock Monitor disabled
    IESO     = Off                                                      ' Oscillator Switchover mode disabled
    PWRTEN   = On                                                       ' Power up timer enabled
    BOREN    = Off                                                      ' Brown-out Reset disabled
    BORV     = 190                                                      ' VBOR set to 1.9 V nominal
    WDTPS    = 8192                                                     ' 1:8192 (approx 30 seconds)
    HFOFST   = Off                                                      ' The Access clock is not held Off until the HF-INTOSC is stable
    PBADEN   = Off                                                      ' PORTB<4:0> pins are configured as digital On Reset
    CCP2MX   = PORTC1                                                   ' CCP2 input/output is multiplexed with RC1
    CCP3MX   = PORTB5                                                   ' P3A/CCP3 input/output is multiplexed with RB5
    T3CMX    = PORTC0                                                   ' T3CKI is on RC0
    P2BMX    = PORTB5                                                   ' P2B is on RB5
    STVREN   = On                                                       ' Stack full/underflow will cause a Reset
    LVP      = Off                                                      ' Single-Supply ICSP disabled
    Cp0      = Off                                                      ' Block 0 (000800-001FFF) not code protected
    CP1      = Off                                                      ' Block 1 (002000-003FFF) not code protected
    CPB      = Off                                                      ' Boot block (000000-0007FF) not code protected
    CPD      = Off                                                      ' Data EEPROM not code protected
    WRT0     = Off                                                      ' Block 0 (000800-001FFF) not write protected
    WRT1     = Off                                                      ' Block 1 (002000-003FFF) not write protected
    WRTB     = Off                                                      ' Boot block (000000-0007FF) not write protected
    WRTC     = On                                                       ' Configuration registers (300000-3000FF) write protected
    WRTD     = Off                                                      ' Data EEPROM not write protected
    EBTR0    = Off                                                      ' Block 0 (000800-001FFF) not protected from table reads executed in other blocks
    EBTR1    = Off                                                      ' Block 1 (002000-003FFF) not protected from table reads executed in other blocks
    EBTRB    = Off                                                      ' Boot block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End

All the demos are running with the AN0 pin left floating with a small piece of wire attached. The library and demos are attached below.

See_Mos

Another method that I tried a while ago was to start a sixteen bit timer and let it rollover then have the user press a button to capture the timer value and use that as the seed.  Following that and after a fixed time the process is repeated.  The chances of the user hitting the same timer value twice are very small.

Frizie

See also examples in the time-honored Positron (Proton) PIC Basic course, part 10.
https://www.picbasic.nl/beginners10.htm

The following example from the course involves rolling a die (a value from 0 to 5) until one of the 6 rolls 250 first.
A 2x16 LCD display keeps track of how many times each number has been rolled.
Every time the PIC is restarted, the result is completely different.

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal
DECLARE XTAL = 4

;Algemene constanten
SYMBOL HoogsteGetal = 5      ;Bepaalt de maximale waarde die getrokken kan worden
SYMBOL LaagsteGetal = 0      ;Bepaalt de minimale waarde die getrokken kan worden

;Compiler berekeningen
SYMBOL DeelFactor  = 65535 / ((HoogsteGetal + 1) - LaagsteGetal) ;Bereken delingswaarde

;Variabele declareren
;BYTE ARRAY
DIM Getal[6]        AS BYTE  ;Array bestaande uit 6 elementen
;WORD
DIM x              AS WORD  ;Met WORD variabele 'x' gaan we de randomizer schudden
;BYTE
DIM RND            AS BYTE  ;In 'RND' komt steeds een willekeurig getal
DIM Teller          AS BYTE  ;Teller voor de FOR...NEXT lus

x = x + EREAD 0              ;'x' voor CLEAR, 'x' is dus nog niet gewist (= willekeurig!)
EWRITE 0, [x]                ;Schrijf het willekeurige getal in 'x' naar EEPROM adres 0 en 1
CLEAR                        ;Wis alle RAM geheugen
x = EREAD 0                  ;Lees EEPROM adres 0 en 1 (x is een WORD variabele) weer uit

DELAYMS 500                  ;LCD stabilisering

GOTO Hoofdprogramma          ;Spring over de subroutine(s)


;Subroutine
Load_RND:
  FOR Teller = 1 TO 11        ;Toevalsgenerator 11x schudden
    SEED x + 2221            ;Verhoog 'x' met 2221, wat een nieuwe startwaarde oplevert
    x = RANDOM                ;Geef willekeurige waarde aan variabele 'x'
  NEXT
  RND = (x / Deelfactor) + LaagsteGetal ;Bereken waarde tussen Laagste- en 'HoogsteGetal'
  IF RND > HoogsteGetal THEN Load_RND  ;Af en toe kan 'RND' hoger worden, dan nog een keer
RETURN


Hoofdprogramma:
CLS                          ;Display wissen

REPEAT                        ;Herhaal...
  GOSUB Load_RND              ;Laad 'RND' met een nieuwe willekeurige waarde

  INC Getal[RND]              ;Verhoog de teller van het getrokken getal (0...5) met 1

  PRINT AT 1, 1,  @Getal[0]  ;Geef op display weer hoe vaak er een 0 is getrokken
  PRINT AT 1, 6,  @Getal[1]  ;Geef op display weer hoe vaak er een 1 is getrokken
  PRINT AT 1, 11, @Getal[2]  ;Geef op display weer hoe vaak er een 2 is getrokken
  PRINT AT 2, 1,  @Getal[3]  ;Geef op display weer hoe vaak er een 3 is getrokken
  PRINT AT 2, 6,  @Getal[4]  ;Geef op display weer hoe vaak er een 4 is getrokken
  PRINT AT 2, 11, @Getal[5]  ;Geef op display weer hoe vaak er een 5 is getrokken
UNTIL Getal[RND] = 250        ;Totdat een zojuist getrokken getal 250 maal is getrokken
END                          ;Belangrijk dat deze END er nu staat

A result of restarting the PIC16F628A:

243  218  250
241  233  241

PRINT AT... displays the current value of each array variable.

Display line 1 shows how many times the numbers 0, 1, and 2 have been rolled in succession, and display line 2 shows how many times 3, 4, and 5 have been rolled.
Ohm sweet Ohm | www.picbasic.nl

Fanie

Thank you all, I can see a lot of thought has gone into this.

Generating a random number can be useful in making insecure remote signals secure.  Instead of sending a fixed number string over the air you can change it, and some synchronizing between the Tx and Rx can keep track of the next expected number string.

The Chinese sell a Tx Rx set 433MHz for ZAR35, which is 22x cheaper for you guys.  Also, the locally available transmitters and receivers are expensive and limited to 4 channels.  The 3 cha is actually a 4 cha, only the 4th tactile switch was not populated and this cost you a lot too much extra.  The receivers only do up to 3 channels and current is too low at 1A if I remember right.

Do I continue on this thread or start a new one ?

charliecoutas

Back in 1956, Tommy Flowers (and others) was asked to design a machine for generating random numbers for Premium Bonds - a method of the government borrowing money from the public and paying prizes (interest) depending on random numbers. Little did they know what else Flowers had designed in previous years - Colossus.

ERNIE was the result: https://en.wikipedia.org/wiki/Premium_Bonds

It used the noise in a neon voltage regulator valve as the basis of the random number. They employed several mathematicians to verify that the numbers were truly random. The neon-discharge tubes were mounted on springs and shielded from external magnetic fields to prevent any fiddling.

We built a replica of the first demonstration machine that Flowers et al built. It is on display at the museum.

(Just between you and me, when the neon vacuum tubes in our replica stop generating noise, guess what takes over? A 16F628A, but don't tell anybody.)

Charlie

Interesting thread Fanie.

Fanie

#8
One thing I can say about pics are that the hardware is excellent.  The pic I use for my gate opener is now probably about 25 years old.  How many clock cycles did it do to now ?  It was exposed to many potentially devastating conditions like lightning, wires that broke off, current sense resistors burning out and more... and it still works every day.

Nothing random about it though, just repeated consistency.  The code was still in ASM and it has a few cute features too.
Just a thought...

Re secure remote coms.
To use a random value securely I have a few ideas.  The Tx send a button number, a user ID, the random number received from a free running counter and the security code  which determine the validity.
The security code is received from a lookup table using the random number, so there is no sequence or value order.

The Rx receives this and use the random value to determine if the security code is correct using the same table.
And finally the code total length can also vary, also from the random number if you want.

Of course if the same previous value is received the signal is rejected so eliminate code grabbers and can even indicate an alarm if this happened.
No one knows what is in your table.
A continuous signal noise alarm, indicate a signal suppressor is active, used by the attackers in Sick Africa when they are sent to murder someone,  who then cannot phone, radio for help or use remotes for ie lights.

A button pressed numerous times by the neighbor's brat baby chewing on the transmitter elsewhere, and after wiping the snot and goo off the remote, does not have to determine where in the algorithm it is requiring more than one transmission.

I think it is going to be really tough to grab a random value signal and determine from that what is where in the table.

Your opinion...

Below is an AI generated question.