Random Seeds and Random Numbers

tim7:

You don't have to use those particular amplifiers, any decent op-amp will do.

NE5532? (Any 5532?) :slight_smile:

Could you just tune in to an empty radio band and read the static?

Hmm... maybe just a length of wire, AC coupling cap, and an opamp + rectifier for static... but I think I'll just use the get-a-random-seed-from-random.org-and-store-next-seed-in-eeprom method. It should suffice for what I need.

But I may look into the radio idea...

Thanks a lot!

baum

Could you just tune in to an empty radio band and read the static?

I believe that's the method used by random.org.

Could you just tune in to an empty radio band and read the static?

I believe that's the method used by random.org.

I believe you are correct.

baum

Hum... Using a radio band (AM-FM) is a good idea. So I could build a simple AM radio (small DIY) tuning coil, with a fix small cap tune with a strong local station , amplify the audio, and get that audio signal into an analog pin of tha Arduino to get a value and use that value has a random seed.

Interesting...

I guess it doesn't matter if what you want is the noise. But it won't be as small or reliable as a cheap radio tuner chip. At least 1 with internal antenna.

tim7:
If non-deterministic randomness is needed as well as non-repeating randomness, you'll need a proper noise generator such as like this one from http://www.maxim-ic.com/app-notes/index.mvp/id/3469:

We don't need the higher frequencies (>10kHz), so filter them out before the first amplifier. You don't have to use those particular amplifiers, any decent op-amp will do. Connect the output to an analogue pin and ensure that the amplitude of the resulting waveform is much larger than the ADC resolution, but still comfortably within the ADC's input range.

More questions about that. The input side looks like a 1st order high-pass filter with a cutoff freq. of 11MHz. So it seems like there won't be much signal left under 10kHz. Maybe a bandpass filter would be better there? And shouldn't there be a DC blocking cap between Vout and Vin? (see Mixed-signal and digital signal processing ICs | Analog Devices)

justjed:
More questions about that. The input side looks like a 1st order high-pass filter with a cutoff freq. of 11MHz. So it seems like there won't be much signal left under 10kHz. Maybe a bandpass filter would be better there?

On my first glance at the Maxim application note I thought the noise spectrum went down to low frequencies (fig 2). Now I'm not so sure about the scale on that graph. The input impedance of that amplifier chip is low: the data sheet implies 50 ohm, which would give a corner frequency of 6.8MHz on the input stage.

Since we're looking for much lower frequencies, a high input-impedance amplifier would be preferred.

You're implying (or, I'm inferring) that the input impedance affects the response characteristics of the filtration. That makes sense to me, as the cap and the impedance of the op-amp together resemble a high-pass filter. Can I analyze that as simply a low-pass filter, followed by a high-pass? IOW, treat them separately, using f=1/(2piRC)?

I decided to go ahead and breadboard this, using on-hand parts. Oddly, that doesn't include any zeners, or 470pF caps. So I got a 3.9V zener from the landlord, and sorta randomly selected capacitors.

This is a plot of the values on A0, measured every 1/2 second.

The values:

113 119 064 041 034 044 071 083 079 056 042 047 072 089 089 069 052 051 070 091
094 081 060 057 070 095 103 083 064 063 079 104 107 077 066 072 097 113 105 074
070 085 108 116 088 075 077 100 121 107 081 080 098 120 123 093 083 087 111 128
113 087 089 109 131 123 093 091 105 134 131 100 095 114 140 132 101 100 132 144
121 101 113 143 144 112 104 132 149 136 110 115 145 151 126 112 129 151 147 120
116 144 157 140 120 127 156 160 135 123 140 162 158 130 126 152 165 151 128 131
161 166 142 127 141 167 164 136 129 154 171 157 132 134 164 172 147 132 146 172
170 141 135 161 175 160 137 142 172 176 150 138 157 178 170 143 142 170 180 157
141 153 179 177 149 144 169 183 167 144 151 181 183 157 146 167 188 177 150 149
179 188 166 148 160 188 187 157 150 177 193 177 153 160 190 194 166 157 180 198
186 161 164 194 199 173 161 180 201 193 166 166 195 204 179 168 187 214 200 163
154 206 214 165 138 151 200 189 131 133 202 205 160 130 161 228 211 132 144 224
231 174 140 172 245 229 142 152 235 242 183 144 167 241 225 141 150 228 237 182
142 170 248 230 139 149 242 246 186 141 166 250 236 139 148 220 194 185 161 165
196 202 171 154 181 200 188 161 164 197 200 172 162 185 204 191 164 171 202 205
175 163 186 206 192 164 165 197 202 173 159 178 201 192 161 163 194 202 177 160
180 206 199 168 168 200 209 181 153 198 238 209
// Checking out reading white noise

void setup()
{
  Serial.begin(9600);          //  setup serial
  analogReference(DEFAULT);
  delay (1000); // give me time to turn on the power supply.
}

void loop () {

  Serial.println(analogRead(0));
  delay (500);
}

At this point, I can just let it run for a bit and see what happens, but I wouldn't mind some feedback before I do that.

Not particularly random in their own right, can you grab the LSBs and construct a few hundred bytes to see what that looks like.


Rob

I changed the code:

void loop () {

for (int i=0; i<200; i++) {
val = lowByte(analogRead(0));

Serial.println(val);
delay (100);
}
Serial.println("Delaying ...");
delay(10000);
}

Initially, this got me

035 226 204 207 235 240 215 202 218 240 236 208 203 229 241 226 204 208 236 241
215 203 220 241 235 208 204 230 242 225 204 210 237 241 214 204 222 241 235 207
205 232 242 224 204 211 238 241 214 204 223 242 234 208 205 232 242 223 204 212
239 241 214 204 224 242 234 208 206 233 242 223 204 213 239 241 213 203 224 242
233 207 206 233 242 222 204 213 239 240 213 204 224 242 233 207 206 233 242 222
204 214 239 240 213 204 225 243 232 207 206 234 242 221 204 214 240 240 212 204
226 242 231 206 207 235 242 220 204 216 241 240 212 205 228 243 232 207 208 236
243 221 205 217 242 241 213 206 229 244 232 208 209 238 244 221 206 219 243 241
213 207 230 246 233 209 210 238 245 222 207 220 244 242 213 207 231 246 233 209
211 239 246 222 208 221 245 243 214 208 232 247 234 210 212 240 247 223 208 222

But after waiting a couple minutes:

084 002 254 008 021 034 036 022 003 255 004 016 032 036 027 007 000 254 010 030
000 036 031 010 255 004 016 032 036 027 006 000 254 010 029 036 031 010 254 004
016 000 032 036 026 006 000 253 010 029 035 031 010 254 003 015 032 036 026 005
255 000 000 009 022 034 035 019 001 253 005 017 032 035 023 004 254 001 012 030
035 028 007 000 000 253 006 019 032 035 022 003 253 002 014 031 035 027 006 255
255 027 035 032 000 012 254 001 011 029 035 029 008 000 253 005 018 032 035 023
003 254 001 012 030 000 035 028 007 000 252 006 019 033 035 022 003 253 001 014
031 035 027 006 255 255 000 026 035 032 012 255 000 010 029 035 030 009 001 253
005 017 033 035 024 004 255 000 001 012 030 036 029 009 001 253 007 019 033 035
023 004 254 002 013 031 036 029 000 008 000 253 006 019 033 035 023 004 255 001
012 030 035 029 008 000 253 005 018 000

Then I noticed that jiggling wires had significant effects. Stray capacitance I guess. Makes me wonder about how well breadboarding works for things like this.

Anyhow, were you asking about just the low 4 bits? Easy enough to mask those off and bit-shift into an 8 or 12-bit integer.

While not super random, I have thought of a built in component of the ATMega328 that is "unpredictable" to a degree. The 328 has a built in temperature sensor that is accurate to +-10 degrees C. The inaccuracy actually works in your favor as a seed.

More information is in the datasheet.

http://code.google.com/p/tinkerit/wiki/SecretThermometer

The inaccuracy actually works in your favor as a seed.

Not in my testing. Bear in mind there is a big difference between "inaccurate" and "unpredictable".

Well, hey, here's another tack:

// Checking out reading white noise

int  val, rval;

const int lmask = 0xF;

void setup()
{
  Serial.begin(9600);          //  setup serial
  analogReference(DEFAULT);
  delay (3000);  // give me time to turn on the power supply.
  Serial.println("Starting read loop...");
}

void loop () {

  for (int i=0; i<200; i++) {

    val = (analogRead(0)) & lmask;
    rval = 0 | (val << 4);
    rval = rval | (analogRead(0)) & lmask;
 
    Serial.println(rval);
    delay (100);
  }
  Serial.println("Delaying ...");
  delay(10000);
}

If I didn't get crosswise with edit windows, that's this block of numbers:

170 152 118 018 068 187 219 119 222 103 153 254 102 188 187 220 119 205 086 170
135 102 017 051 170 203 118 205 102 152 254 086 018 068 170 169 101 221 102 135
237 085 018 051 153 152 085 119 001 119 084 033 101 188 085 153 085 118 136 034
153 152 084 102 239 136 084 102 120 018 136 152 068 085 103 136 236 102 120 018
120 151 068 085 119 152 220 085 051 018 034 135 101 051 085 136 119 169 068 068
068 068 119 033 068 035 018 034 119 067 084 034 240 085 101 220 034 188 051 118
015 050 034 035 034 102 017 067 034 001 188 101 050 067 017 239 068 085 084 084
017 204 051 085 101 033 034 052 034 085 135 033 017 017 017 068 169 033 000 085
137 068 203 051 000 051 103 068 237 067 015 137 017 051 118 000 255 240 051 034
000 118 255 085 034 034 050 050 254 035 017 050 084 051 238 017 000 051 255 084

I also note that there appears to be a settling time involved -- results were better when I just left the circuit powered up when uploading a new sketch, and if I cycled power on the circuit while the sketch was running, I'd get significant clumping at first. Does that imply needing smaller caps -- at least on the input side? (Or a smaller load resistor, i.e. higher current through the zener?)

ETA: I'm using the TI NE3352P dual op-amp IC.

There is some very obvious clumping there. Rather than using nibbles can you accumulate just the lowest bit from each reading.


Rob

I might experiment with that. However, I recall reading some material, a while back, on the clumping phenomenon, and IIRC, it isn't necessarily an indictment of the randomness of a sequence. I will have to delve into that a bit. The classic example is the theoretically perfect coin toss. If the result of a sequence of tosses was always head - tail - head - tail - head - tail alternating, then that would not be considered random. I had hoped to find something informative at Wolfram, but no dice on my initial search. Fortunately, I know a few competent mathematicians.

I would, however, be much interested in suggestions for improving the circuit. If there's too much bit-banging needed to use it as a good RNG, then it won't be useful as a breakout board. I'm not striving for a DOD level cryptographic thing here (or whatever super certification you can think of), just something useful, and which doesn't require much processing oomph.

ETA: BTW, I was mostly curious about how well it might work to do what Tim7 suggested -- reading the output on an analog pin. As in the Intel dual-inverter method, the output should be "whitened", using something like von Neumann filtering, and in the case of this circuit, the signal would need to feed through a Schmitt trigger prior to that. Maximal success, it seems to me, would then require that the output voltage be swinging through a wider range. With output values hitting a max (so far) of 255, that's only 1.25 volts, and not adequate for producing a logical bitstream. Well, that's accepted practice, anyway, at least from what I've been reading.

p.s. And, since I'm thinking along other lines, of course, it took a moment to consider that one could use a Schmitt trigger with a threshold at the mean of whatever the output is -- I assume there are many varieties available.

Schmitt trigger with a threshold at the mean of whatever the output is -- I assume there are many varieties available.

Which threshold? The high one or the low one?

btw: would it be possible to feed a (regular) inverter a voltage inside "no-man's" zone? Would this produce a randomish bit stream? (i.e. for the 7404 the min. high voltage is 2V, yet the max. low voltage is .8V. So what would happen @, say, 1.3V (arbitrarily chosen)?)

baum

What do you consider to be the flaws? I think it's a flaw to throw away all the bits except the last one, since the others could have randomness, too. And it's a flaw to sample a floating pin, since the signal on that pin varies wildly from one circuit and environment to the next. It could be held to ground by parasitics and the ADC would output nothing but 0s.

I tried testing TrueRandom on my Duemilanove and it does not look "truly random".

~> ent TrueRandom.bin
Entropy = 7.544390 bits per byte.


Optimum compression would reduce the size
of this 92810048 byte file by 5 percent.

Chi square distribution for 92810048 samples is 131287892.21, and randomly

would exceed this value 0.01 percent of the times.

Arithmetic mean value of data bytes is 93.7178 (127.5 = random).
Monte Carlo value for Pi is 3.682216212 (error 17.21 percent).
Serial correlation coefficient is -0.008583 (totally uncorrelated = 0.0).

which is "almost certainly not random". The numbers it gives are clumped around 0 and powers of 2, which I think just means it spits out lots of 0s and few 1s.


Imgur

endolith:
What do you consider to be the flaws?

It may take a few days to resurrect the memories. I'll get back to you.

I think it's a flaw to throw away all the bits except the last one, since the others could have randomness, too.

I'm confused. You state it's a flaw to throw away all but the last bit but then prove even the last bit is not random.