Rasgele bir sayı üreteci için en küçük ve en basit tohum hangisidir?


40

Küçük bir mikrodenetleyici (8-bit Atmel), çok sayıda süslü randomize ışık sekansı içeren bir ışık gösterisi sunmak için birçok ışığı kontrol eder.

Uygun bir sözde RNG işini iyi yapıyor, ancak bunun için iyi bir tohum arıyorum. Bir tohum gerekli olacaktır, çünkü eğer birisi aynı anda birden fazla cihazı çalıştırırsa, ayrı ayrı saat kaynaklarındaki küçük farklar nedeniyle yavaşça ayrılmadan önce aynı etki dizilerini oluşturmaları iyi görünmeyecektir.

Sık kullandığım sahte RNG'yi tohumlamak için çok iyi bir yöntem, bir düğmeye basılması veya bir anahtarın çevirilmesiyle başlatılması gereken bir cihaz olması durumunda mümkündür. Μc açılır açılmaz çok hızlı bir zamanlayıcı başlatılabilir ve bu zamanlayıcının değeri düğmeye ilk kez basıldığında RNG'yi verir.

Sorun, bu senaryoda, hiçbir düğme olmamasıdır. Cihaz açıldığında programın başlaması gerekir.

PCB üzerindeki yer son derece sınırlıdır (en küçük SMD parçalarından birkaçının sığabileceği bir şey değildir), bu yüzden mümkün olan en küçük ve en basit çözümü arıyorum. Bu nedenle, gerçek RNG donanımı, radyo alıcıları vb. Gibi fantezi çözümlerini ekarte edeceğim.

Sahip olduğum tek şey CPU'da 16 bitlik bir zamanlayıcı-sayacı ve bir ADC'ye erişimi olan kullanılmayan bir portpin.

Mevcut çözümüm, ADC pimine besleme geriliminin yaklaşık yarısını sağlamak için sadece bir direnç kullanmak (mümkün olduğunca yanlış) ve RNG'yi ilk AD dönüşüm değeri ile tohumlamaktır. Bununla birlikte, günümüzde çoğu% 10 direnç% 1'in altında bir yanlışlığa sahiptir (bulabilecekleri en kötü kalite SMD dirençlerini istediğimizi söylediğimde bir tedarikçinin yüzünü hayal etmek eğlenceli olacaktır), bu yüzden çok yüksek bir şansı var. aynı tohum ile başlayan çoklu birimler.

Daha iyi bir alternatif, birden çok dönüşüm yapmak ve bu ölçümlerin en az önemli bitlerinden bir değer oluşturmaktır. Ancak, bu µc türünün ADC'sini daha önce kullandım ve çok doğru olduğunu biliyorum. ADC'yi mümkün olan en yüksek hızda çalıştırmak burada yardımcı olabilir.

Daha iyi bir öneriniz var mı? Tohumun düzgün bir şekilde düzgün bir şekilde dağılması gerekmez, ancak dağılım ne kadar düzgün olursa, o kadar iyidir. Kusursuz bir formata sahip 16 bitlik bir tohum, gerçek olamayacak kadar iyi bir rüya olurdu, ama 5 ya da 6 bitin üzerinde yarı yarıya iyi bir dağılımın yeterli olabileceğini düşünüyorum.


12
"Bir tedarikçinin yüzünü, bulabilecekleri en kötü kalitede SMD dirençlerini istediğimizi söylediğimde hayal etmek eğlenceli olurdu" - bu rezistörün değerinin devre şemasında tanımlanmamasına izin vermek daha da komik olurdu ve pcb yerleştirme makinesinden çıktıktan sonra, sahip olduğumuz her direnç değerini bir araya getirdiğimiz bir çöp kutusundan bu parçanın elle lehimlenmesi gereken üretimdeki insanlar. - Çünkü aradığım bir RNG değil, tohum . Bu yüzden hemen hemen her seferinde aynı değeri üretirse, o kadar da kötü değildir, cihazlar arasında farklı olmak daha önemlidir.
vsz

8
Üretim programlaması sırasında neden EEPROM deposuna rastgele bir değer yazmıyorsunuz? Bu şekilde, yalnızca üretim programcılarında olduğu gibi son cihazlarda değil, beğendiğiniz en havalı RNG'yi kullanabilirsiniz. (@ İmmibis'e teşekkür: 'biraz farklı yazılım dosyanız' bana bir fikir verdi.)
Calrion

2
Bu yüzden sadece% 100 net olmak gerekirse, sorun aynı sırayla başlayabilecekleri, zaman içinde kaymayacakları değil, doğru, değil mi?
Çar 3'15 15’de

2
RNG'nizin seçimi önemlidir: bazıları kaliteli tohumlara ihtiyaç duyar, bazıları istemez. Örneğin, Xorshift için 0'dan başka herhangi bir tohum işe yarar ve eşit derecede çalışır. İlk tohumdaki küçük bir fark bile, RNG döngüsünde çok farklı bir başlangıç ​​pozisyonuna neden olacaktır.
curiousdannii

3
Tüm ADC cevaplarını daha fazla rastgelelik için istatistikler ve zamanlama ile birleştirebilirsiniz. Örneğin, alt 3 LSB'lerin 101 olduğu N örneklerini ve alt 3 LSB'lerin 110 olduğu M örneklerini alana kadar ne kadar işlemci kene aldığınızı ölçün. Bu kavramı istediğiniz gibi genişletin.
wjl

Yanıtlar:


24

A / D pimi ile toprak arasına paralel bir direnç ve kapasitör yerleştirin. Rezistörü oldukça yüksek, tercihen A / D için giriş sinyali empedans şartının çok üstünde yapın. RC zamanını belki 10 µs civarında sabitleyin. Örneğin, 100 kΩ ve 100 pF iyi bir kombinasyona benziyor.

Rastgele bir değer elde etmek için pimi bir süre yükseğe sürün, ardından yüksek empedansa ayarlayın ve birkaç µs sonra A / D okuması yapın. Özellikle, A / D toplama zamanını doğru bir şekilde kötüye kullanırsanız, göreceği voltaj R ve C değerlerine, pim kaçak akımına, yakındaki diğer gürültüye ve sıcaklığa bağlı olacaktır.

Düşük bit veya düşük iki bit tut ve istediğiniz sayıda rasgele bit elde etmek için gerektiği kadar tekrarlayın.

Daha rastgele bir patern için bu prosedürü ara sıra uygulayın ve A / D sonucunun düşük bitini zaten kullandığınız rasgele sayı üretecine enjekte edin.


Bu iyi geliyor. ADC'deki giriş empedansını kontrol ettiğinizden emin olun - Atmega8 serisi Olin'in direnç değerini biraz düşük yapan 100Meg'lik analog giriş empedansına sahiptir.
stefandz

3
@stef: Giriş empedansı ve doğru dönüşüm için gerekli olan sinyal empedansı iki farklı şeydir. Evet, giriş empedansı CMOS olması nedeniyle çok yüksektir. Bununla birlikte, sinyalin numuneyi şarj etmesini ve belirtilen süre içinde kapağı tutmasını sağlamak ve pimin sahip olabileceği sızıntıyı gidermek için bir maksimum empedans sınırı vardır.
Olin Lathrop

2
Üzgünüm, cevabınızdan kaynak empedans spesifikasyonunun aksine giriş empedansını referans aldığınızı sanıyordum. 10k, Atmega8'in belirtilen maksimum kaynak empedansıdır, bu nedenle cevabınız açıktır. Referans olarak, herhangi birinin ilgisini çekmesi durumunda, içindeki S / H kapağı 14pF'dir.
stefandz

2
@ stef: Cevabı daha net yapmak için düzenledim.
Olin Lathrop

Ay evresi ve resmi tatil günlerini kaçırdınız. Ayrıca, özellikle düşük C ve iyi korumalı değilse, el ile yararlı bir ekleme sallayarak.
Russell McMahon

23

Bazı olası seçenekler:

  1. Her cihaz için benzersiz bir seri adresi önceden programlayın. Yeterince iyi bir RNG algoritmasına sahipseniz, sıralı bir seri adres listesi bile çılgınca farklı sonuçlar verecektir.

  2. MCU'nuza / kurulumunuza bağlı olarak, sistem saati ve bekçi saati / zamanlayıcı sayacı girişi için iki farklı saat kaynağınız olabilir. Bunlardan birinin / her ikisinin de önemli farklılıkları varsa, bunu uygun şekilde farklı bir tohum üretmek için kullanabilirsiniz. İşte Arduino'nun dahili bekçi saati sayacını ve harici bir XTAL sistem saatini kullanan bir örnek .

  3. BJT transistörü kullanın ve yüksek oranda beta bağımlı bir amplifikatör oluşturun. Bu, tohum için bir ADC'den okunabilir.

  4. Kondansatörler / indüktörler tipik olarak dirençlerden çok daha kötü bir toleransla belirtilir. Bunlarla bir çeşit filtre devresi (RC, RL, LC) oluşturabilir ve çıkışı ADC ile ölçebilirsiniz.


5
Seçenek 1 için oy kullanıyorum, dizilerin asla eşleşmemesiyle sonuçlanacak olan sıfır parça sayma çözümüdür. Seri numarası ve RND jeneratörü, herhangi bir cihazın diğerinin modelini taklit etme ihtimalinin ihmal edilebilir olduğunu söyleyen 16 bit diyebilir.
KalleMP

1
Ben de çözüm olanı sevdim. Basit bir karma algoritması kullanıyorsanız, sıralı seri numaralarınız olsa bile iyi olmalısınız.
magu_ 21

6
Seçenek 1 ile ilgili güzel bir şey, bazı cihazların yerleşik seri numaralarıyla (genellikle ağ / RF ile ilgili
mikroskoplar) gelmesidir

3
Hatta böyle bir çöp RNG LCG olacak "seri adresleri sıralı liste için çılgınca farklı sonuçlar" . Ben de 1 oy verdim.
BlueRaja - Dany Pflughoeft

3
Eğer bir zaman kaynağınız varsa, bunu tohumdaki düğmeniz için bir üs olarak kullanmak, koşular arasındaki şeyleri dengelemeye yardımcı olacaktır. Cihazınızda bir tane varsa ve cihaz içi eşleşmeyi de düzeltirseniz, bunu bir seri adresi / numarası veya MAC adresiyle birleştirin. Bir yeniden başlatma işleminden sonra bile, tohum olarak kullanılmak üzere oluşturulan her rastgele sayının bir kısmını veya tamamını kalıcı olarak saklayan bir yazılım gördüm. Cihazlarınızın farklı çalışma süreleri varsa, birbirinden ayrılmalıdır.
TafT

8

Başlatılmamış hafıza

Başlatılmamış belleği mikro denetleyicide kullanmayı deneyebilirsiniz. İşin püf noktası, en 'dengeli' flip-flop'lara sahip olan ve aslında rastgele olan bitleri bulmak. İşlem, tüm belleğin okunması, sıfırlanması ve hangi bitlerin gerçek anlamda rastgele olduğunu ölçmek için birkaç kez tekrar etmektir. Sonra bu haritayı PRNG veya LFSR'nizi tohumlamak için rastgele bitleri okumak için kullanın!

Bu yöntem size rastgele tohumlar vermeli, aynı donanımda bile olsa, bu günlük hack makalesinde daha fazla ayrıntı (ve bağlantı) bulunmaktadır.

Bu yöntemi seviyorum, çünkü herhangi bir ek devre ya da pim gerektirmiyor; AVR'nizde zaten ram var, sadece kararsız (rastgele) bitleri bulmanız yeterli. Ayrıca haritalama prosedürü otomatikleştirilebilir; Her cihaza aynı kodu ve prosedürü uygulayabilir ve gerçekten rastgele sonuçlar elde edebilirsiniz!


1
Hangi bitlerin rastgele olduğunu bulmanız gerekmez. Tüm baytları XOR'lamak, yalnızca 8 bit rastgele olsa bile size rastgele bir sonuç verir. Resimde görüldüğü gibi, gerçek değerler zamansal anlamda rastgele olmayabilir, yeterince benzersizdirler - bu tam olarak ihtiyacımız olan şey.
MSalters,

1
Entropiyi "karıştırmanıza" izin veren bir PRNG bulabilirseniz, bu XOR-then-seed seçeneğinden bile daha iyi olabilir. Başlatılmamış bellekte yineleme yapın ve baytlarda PRNG'ye karıştırın. Örneğin, basit ve C kütüphaneme bakınız — mix işlevi .
Craig McQueen

Bu size şifreleme kalitesinde rastgelelik kazandırmayacaktır.

@CamilStaps elbette olmaz.
Navin

1
Bu işe yaramayacak. Bir işletim sistemim varsa ve programıma belleğin hangi kısmının atanacağı ve daha önce ne olduğu konusunda herhangi bir kontrolüm yoksa başlatılmamış hafıza tanımsız bir davranıştır. İşletim sistemi olmayan bir mikroişlemci üzerinde bu durum böyle değildir. Özellikle AVR ile, kapasitörlerin mevcut tüketim tarafından boşaltılması için yeterli zaman geçmesi durumunda tüm RAM'ler sıfır olacaktır.
vsz

7

Rasgele özelliğe sahip bir MP3 çalar için yaptığım, her açılışta sadece farklı bir sıralı tohum kullanmak. 1'de başladım ve bunu EEPROM'da sakladım, böylece sonraki güç döngüsünde 2 vs. kullandım. Bu bir ATMEGA168'deydi. Helloworld922'nin dediği gibi basit bir sıralı tohum bile tamamen farklı sahte rasgele sıralar üretecektir.

Doğrusal uyumlu rasgele dizilim jeneratörlerinden birini kullandım, bu tek biçimli bir dağılım verir.

int i;
seed = seed * 2053 + 13849;
i = (seed % max) + 1;  // max is the maximum value I want out of the function

Elbette, aynı sayıda güç döngüsüne sahip olsalar bile, birden fazla birimin farklı dizilere sahip olmasını istiyorsanız, rastgele başlamak için bir şeye ihtiyacınız vardır.

Bu, diğer posterlerin önerdiği yöntemlerden herhangi biriyle yapılabilir - Aklınıza gelebilecek bir yöntem, eğer varsa, işlemciye giden AC sıfır geçişini kullanabilir mi (örneğin lamba faz kontrolü için)? Bu, açılmanın ardından ilk geçiş üzerinde zamanlayıcıyı örneklemek için kullanılabilir ve daha sonra tohum olarak kullanılabilir.

Mod vb. Seçmek için ünitede herhangi bir buton var mı? Eğer sayacı ilk kez örnekleyebiliyorsanız, MCU programlandıktan sonra düğmeye basılırsa, başlangıçta rastgele bir tohum üretebilir ve onu EEPROM'da saklayabilirsiniz. Bu noktadan sonraki her açılışta saklanan tohum kullanılır.


5

ADC, rastgelelik için çok iyi bir kaynaktır.

Direnç toleranslarına güvenmenize gerek yoktur. Herhangi bir direnç termal gürültü üretecektir ve aynı fiziksel etki tüm örnekleme ve dönüştürme adımlarını yaparken ADC'ye gürültü getirecektir. (Veri sayfası size gürültü miktarını ve hangi yapılandırma ayarlarının en kötü / en iyi olduğunu söyleyecektir.)

ADC pimini yüzmeye bırakmamalısınız; bu voltajın çok fazla dalgalanmasına neden olabilir ve girişi doyurma riskini doğurabilir.
(Birçok MCU, kalibrasyon için, besleme geriliminin yarısı gibi bir ADC girişi olarak kullanmanıza izin verir. Bu, harici direnci korur ve yine de size gürültü verir. Yine, en kötü / en iyi yapılandırma veri sayfasını inceleyin.)

Tek bir ADC ölçümüne güvenmenize gerek yoktur; Birden fazla ölçümü basit bir karma veya sağlama toplamı işleviyle birleştirebilirsiniz (CRC yeterli olacaktır). Hemen RNG kullanmaya başlamanız gerekirse, daha sonra ADC sonucunu mevcut RNG çekirdeği ile birleştirebilirsiniz.


2
Johnson gürültüsünün bu uygulamada uygun olduğundan emin değilim; STP'de, 10kHz'lik bir bant genişliğinin üzerinde bir 10Meg direnç 40uVJohnson gürültüsüne sahiptir. Bunu makul bir şekilde ölçmek için> 14 bit ADC veya bir amplifikatör devresine ihtiyacınız olacaktır.
helloworld922

STP gerçekten alakalı değil. Özellikle sıcaklık özellikle kasıtlı olarak yükseltilebilir, ancak STP'ye göre fazladan 60 derece sadece% 10'luk fazladan gürültüdür.
MSalters

1
Benzer bir yaklaşım, atış sesini bir diyotta kullanmak olacaktır. en.wikipedia.org/wiki/Noise_generator#Shot_noise_generators
teambob

2

Tohumculuğu seanstan seansa kaydedebilir misin? Öyleyse, oluşturulduktan sonra her birimi rastgele bir süre için açmak mümkün mü? Bu şekilde tüm birimler aynı olması muhtemel olmayan önceden ayarlanmış tohumlarla gönderilecektir.

Başka bir düşünce: Birden fazla üniteyi nasıl birbirine bağlarsınız, böylece aynı anda açılırlar? Seri halde bulunuyorlarsa, bir tür kapasitör ekleyin, böylece (n + 1) cihazı, cihazdan sonra birkaç saat döngü başlasın. İdeal olarak, kapasitörler cihazın kapanması üzerine çok hızlı boşalır, bu nedenle her başlatma / yeniden başlatma sekanslar arasında daha büyük bir boşluk vardır.

Paralellerse, başlangıç ​​süresini biraz daha rastgele ayarlayabilirsiniz. Kondansatörler kullanarak bir çeşit güç filtrasyonu olduğunu varsayıyorum. Eğer öyleyse, cihazları farklı filtreleme devreleriyle imal etmek, her bir cihazın bir miktar farklı bir zamanda başlamasına ve birkaç yeniden başlatmanın ardından sapmaya neden olur.

Bunun bir varyasyonu, eğer mümkünse, saat sinyallerinize bir değişim eklemesidir. Saat hızındaki% 0.1'lik bir fark, PRNG masasını çok hızlı bir şekilde geçtiğiniz oranını değiştirirken, ışık şovunda çok az etkili olabilir.


1
Muhtemelen büyük bir akıntıyı pimdeki analoga bağlayın ve RNG'yi tohumlamak için "ana hum" un bazı okumalarını yapın.
Jasen,

1
@Jasen, aynı uzatma kablosuna bağlı tüm üniteler aynı elektrik kaynağını görecektir.
Ian Ringrose,

2

Dahili "kalibre edilmiş" saat kaynağında çalışıyorsanız. EEPROM'a tercih edilebilecek bir süre sonra bir tohumdan tasarruf edemez misiniz? Saat sürüklenecek ve üniteden üniteye değişecektir. Bir süre sonra tekrar yeni bir değer kaydetmek için (belki de her 10 dakikada bir, veya cihazın normal açık zamanında gerçekleşecek kadar kısa bir süreden sonra). Cihaz ne kadar uzunsa o kadar çok EEPROM'a "farklı" bir değer.

Ayrıca her defasında bir kez ve sonra (sık sık değil) bir adım atın ve cihaz açıkken yeniden tohumlayın (bu yeni değeri EEPROM'a kaydedin).


2

Bir LDR veya termistör ekleyerek orijinal AD dönüştürme fikrinizi değişken bir direnç temelinde genişletmeye ne dersiniz? (Birincisinin dışardan "bakabilmesi" gerekir, bunun mümkün olup olmadığını bilmem; ancak ışıktaki değişkenlik, yaklaşık aynı yerde yaklaşık aynı anda başlatılan cihazlar arasındaki sıcaklıktaki değişiklikten daha yüksek olabilir. ..)


1
Termistörler başka bir kullanışlı özellik ile birlikte gelir. Çoğu üreticiden elde edilen birkaç seride muazzam farklılıklar ve yanlışlıklar var. Bu, sonucu daha da "iyileştirecektir".
Ariser,

1

Her ikisi de birim başına benzersiz bir ekmeğe ihtiyaç duyduğunuzu varsayarak 2 potansiyel çözüm.

  1. Ünitelerinizi fabrikada birer birer yakarsanız, onaltılık dosya programlayıcıdaki bazı ara komut dosyası tarafından programatik olarak değiştirilebilir. Bilgisayar kontrollü ise, tarih ve saate göre değişken başlatmanın üzerine yazabilirsiniz. Her birim için benzersiz olacağının garantisi!

  2. Dallas 1 kablo cihazları sadece bir pin kullanır ve her biri 64 bitlik seri numarasına sahiptir. Bunu tohum olarak kullanabilirsiniz.


1
Ben 2'yi severim ama maalesef DS'nin parçaları oldukça pahalı.
Ariser,

Kripto kalitesinde rastgelelik için üretim zaman damgası kullanmayın, bu tahmin edilebilir.

2
@CamilStaps OP'nin başvurusu için kripto kalitesine gerek yok
Hagen von Eitzen

1
@HagenvonEitzen doğru, ancak başkaları kripto-Q rasgeleliği arayan bu soruya gelebilir, bu yüzden bahsetmeye değer.

4
@CamilStaps Sigh , sanki insanlıktan vazgeçmişsin gibi görünüyor :) Gerçekten de, ınsetalse'den bir cevabı kriptografik amaçlar için kullanmak isteyen birinden, en azından cevaplaması gereken soruyu okuyacak kadar dikkatli olmalarını beklemek çok mu talep ediyor? ? "16bit" veya "5 o5 6 bit" tohumlar bir grup Schrödinger kedisi tarafından
üretilse

1

Rasgele sayı üretecini (RNG) yakalanan gürültüyle beslemek için kayan bir ADC pini bırakabilirsiniz. Bir tohum üretmek veya onu RNG jeneratörü olarak kullanmak bile yeterli olmalıdır.

Mümkün olan minimum dönüşüm süresini kullanmayı unutmayın.

Diğer çözüm , ADC pimine uygulanan bir ses üreteci olabilir .


2
Bazı ölçümler yapacağım ancak doğru hatırlıyorsam kayan bir ADC pini okuyor 0veya yakın 0. Durumun böyle olup olmadığını görmek için tekrar kontrol edeceğim.
vsz

1
İlgileniyorum, 0yüzerken okuyor mu?
Bence Kaulics

2
Sorun, bunun bir geliştirme kurulu üzerinde çalışabilmesi ve nihai üründe başarısız olabilmesidir.
vsz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.