{"id":2114,"date":"2021-09-19T18:30:32","date_gmt":"2021-09-20T01:30:32","guid":{"rendered":"https:\/\/partofthething.com\/thoughts\/?p=2114"},"modified":"2021-09-19T22:07:23","modified_gmt":"2021-09-20T05:07:23","slug":"making-true-random-numbers-with-radioactive-decay","status":"publish","type":"post","link":"https:\/\/partofthething.com\/thoughts\/making-true-random-numbers-with-radioactive-decay\/","title":{"rendered":"Making true random numbers with radioactive decay"},"content":{"rendered":"\n<p>I plugged my Geiger counter&#8217;s audio cable into my oscilloscope just for kicks the other day and saw ~9V pulses coming out when it occurred to me that I could easily read those into an Arduino or Raspberry Pi or ESP8266 microcontroller and respond to them. As a demo, I made a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Hardware_random_number_generator\">hardware random number generator<\/a> (HRNG) out of a esp8266. <\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Using radiation to generate random numbers\" width=\"660\" height=\"371\" src=\"https:\/\/www.youtube.com\/embed\/lydhprdvVmc?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption>The project<\/figcaption><\/figure>\n\n\n\n<!--more-->\n\n\n\n<p>While we all know radioactive decay is random, converting random clicks into random numbers may not be immediately obvious. One great way of doing it is to use the timings between pulses as a random variable and compare the length of time between two subsequent pairs of pulses. If the length of the first gap is bigger than the length of the second, you emit a 1. Otherwise, you emit a 0. When you have enough bits to build an integer (or whatever kind of number you&#8217;re seeking), you emit the fully-assembled bitstream. <a href=\"https:\/\/www.fourmilab.ch\/hotbits\/how3.html\">Hotbits has a good explanation here<\/a>. <\/p>\n\n\n\n<p>First step as usual was to step the pulses from the Gieger counter down to around 3.3V for the ESP8266&#8217;s GPIO digital input pins. For this, as usual, I just made <a href=\"https:\/\/en.wikipedia.org\/wiki\/Voltage_divider\">a little voltage divider out of 2 resistors<\/a>. I grabbed them out of the grab bag until I had the ratio right, ending up with 22 kOhm and a 10 kOhm one. This brought pulses from around 7V peak down to an appropriate range. <\/p>\n\n\n\n<p>For coding, I used ESP8266 GPIO interrupts. I made an interrupt that fires when the GPIO pin is RISING from LOW to HIGH (e.g. when a pulse is coming in). Here&#8217;s how it looks:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n#define GEIGER_INPUT D6\n\nunsigned long timePrev;\nunsigned long duration1;\nunsigned long duration2;\nunsigned int pulseCount = 0;\nunsigned int bitCount = 0;\nbool flag = false;\nbyte bits;\nint numBits = 8;\/\/ sizeof(bits);\n\nvoid setup()\n{\n  Serial.begin(9600);\n  Serial.println(\"Welcome To Radbits 8000\");\n  pinMode(GEIGER_INPUT, INPUT);\n  attachInterrupt(digitalPinToInterrupt(GEIGER_INPUT), handle_pulse, RISING);\n}\n\nICACHE_RAM_ATTR void handle_pulse(void) {\n    flag = true;\n    switch(pulseCount) {\n        case 0:\n        case 2:\n            timePrev = micros();\n            break;\n        case 1:\n            duration1 = micros()-timePrev;\n            break;\n        case 3:\n            duration2 = micros()-timePrev;\n            break;\n    }\n}<\/code><\/pre>\n\n\n\n<p>I&#8217;m running a pulseCount that increments from 0 to 3 and then loops around each time a pulse comes by (triggered by <code>flag<\/code>). The 1st and 3rd pulse reset the timePrev while the 2nd and 4th pulses compute the two durations. Once 4 pulses have come through, I have 2 durations that are ready for comparison. <\/p>\n\n\n\n<p>You only ever want to do relatively simple things in interrupts, so that&#8217;s all that does. In the main loop, there&#8217;s a function that monitors for the flag being set by the interrupt and it does the rest of the work. It waits until all 4 pulses have been received and then it compares the two durations and sets the next bit in our bits variable. Once we have enough bits, it emits the final fully assembled number and starts over.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void processPulses() {\n    if (!flag) {\n        return;\n    }\n    flag = false;\n  \n    if(pulseCount == 3) {\n        \/\/ durations are prepared. process and reset\n        pulseCount = 0;\n        if (duration1 == duration2) {\n            \/\/ durations equal. Reject and wait for next \n            return;\n        }\n        if (duration1 &gt; duration2) {\n            \/\/ Set this particular bit to 1\n            bits |= (1&lt;&lt;bitCount);\n        }\n        else {\n            \/\/ set this bit to 0\n            bits &amp;= ~(1&lt;&lt;bitCount);\n        }\n        bitCount++;\n        if(bitCount == numBits) {\n            bitCount = 0;\n            emit();\n        }\n    }\n    else {\n        pulseCount++;\n    }\n}\n\n\nvoid emit() {\n    Serial.println(bits);\n}\n\nvoid loop() \n{\n  processPulses(); \n}<\/code><\/pre>\n\n\n\n<p>That&#8217;s it. Fun little project for sure. <\/p>\n\n\n\n<p>Here&#8217;s a histogram of the results after running for a few minutes. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/results.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/results-1024x768.png\" alt=\"\" class=\"wp-image-2116\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/results-1024x768.png 1024w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/results-300x225.png 300w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/results-768x576.png 768w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/results-1536x1152.png 1536w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/results.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Some radiation-derived random numbers<\/figcaption><\/figure>\n\n\n\n<p>A file full of numbers from it is available here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/data-1.txt\">Random data<\/a><a href=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/data-1.txt\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p>I will probably use this Geiger counter interface for more stuff later. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>I plugged my Geiger counter&#8217;s audio cable into my oscilloscope just for kicks the other day and saw ~9V pulses coming out when it occurred to me that I could easily read those into an Arduino or Raspberry Pi or ESP8266 microcontroller and respond to them. As a demo, I made a hardware random number &hellip; <a href=\"https:\/\/partofthething.com\/thoughts\/making-true-random-numbers-with-radioactive-decay\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Making true random numbers with radioactive decay<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[3,69,5],"tags":[],"class_list":["post-2114","post","type-post","status-publish","format-standard","hentry","category-computers","category-electronics-and-physics","category-nuclear"],"_links":{"self":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/2114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/comments?post=2114"}],"version-history":[{"count":5,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/2114\/revisions"}],"predecessor-version":[{"id":2123,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/2114\/revisions\/2123"}],"wp:attachment":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/media?parent=2114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/categories?post=2114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/tags?post=2114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}