Συνάρτηση τυχαίων αριθμών Arduino. Χρήση μιας γεννήτριας τυχαίων αριθμών στο Arduino: Λειτουργίες Τυχαίων και Τυχαίων Αριθμών

Πολλά έχουν γραφτεί για τις γεννήτριες τυχαίων αριθμών, αλλά σχεδόν πάντα, όταν πρόκειται για υλοποίηση, υπονοείται (ή δηλώνεται ρητά) ότι μιλάμε για x86/x64 και άλλες αρχιτεκτονικές «ενήλικες». Ταυτόχρονα, τα φόρουμ που είναι αφιερωμένα στην ανάπτυξη συσκευών σε μικροελεγκτές είναι γεμάτα ερωτήσεις "πώς μπορώ να δημιουργήσω έναν τυχαίο αριθμό στο %controllername%;" Επιπλέον, το εύρος των απαντήσεων εκτείνεται από «κοιτάξτε το Google/Wikipedia» έως «χρησιμοποιήστε την τυπική λειτουργία». Αυτή η «τυπική συνάρτηση» δεν υπάρχει πάντα και ταιριάζει στον προγραμματιστή από όλες τις απόψεις· τις περισσότερες φορές συμβαίνει το αντίθετο: μερικές φορές οι αριθμοί δεν είναι τυχαίοι, μερικές φορές η ταχύτητα λειτουργίας είναι πολύ χαμηλή ή μερικές φορές ο κωδικός που προκύπτει δεν ταιριάζει σε ελεύθερη μνήμη καθόλου.
Ας προσπαθήσουμε να καταλάβουμε ποιοι είναι οι αλγόριθμοι δημιουργίας τυχαίων αριθμών, πώς να επιλέξετε τον σωστό και το πιο σημαντικό, ποια είναι τα χαρακτηριστικά της εφαρμογής αυτών των αλγορίθμων σε ελεγκτές.

Αξιολόγηση της «τυχαιότητας»

Οι εφαρμογές για RNG μπορεί να είναι πολύ διαφορετικές, από παιχνίδια μέχρι σοβαρή κρυπτογραφία. Κατά συνέπεια, οι απαιτήσεις για τη γεννήτρια ποικίλλουν επίσης πολύ. Υπάρχουν ειδικές δοκιμές για την αξιολόγηση της ποιότητας (επίπεδο «τυχαίας») της γεννήτριας. Εδώ είναι τα πιο βασικά από αυτά:
  • Δοκιμή συχνότητας. Αποτελείται από την καταμέτρηση του αριθμού των μηδενικών και των μονάδων σε μια ακολουθία bit. Θα πρέπει να υπάρχουν περίπου ίσοι αριθμοί μονάδων και μηδενικών.
  • Δοκιμή για μια ακολουθία πανομοιότυπων bits. Αναζητούνται σειρές πανομοιότυπων bit, όπως 000...0 ή 111...1. Η κατανομή των συχνοτήτων με τις οποίες εμφανίζονται οι σειρές, ανάλογα με το μήκος τους, θα πρέπει να αντιστοιχεί σε αυτήν την κατανομή για ένα πραγματικά τυχαίο σήμα.
  • Φασματική δοκιμή. Ένας διακριτός μετασχηματισμός Fourier εφαρμόζεται στην αρχική ακολουθία. Το προκύπτον φάσμα δεν πρέπει να έχει σημαντικές κορυφές που θα υποδεικνύουν την παρουσία περιοδικών ιδιοτήτων της αλληλουχίας.
  • Τεστ αυτοσυσχέτισης. Υπολογίζεται η τιμή συσχέτισης μεταξύ των αντιγράφων αλληλουχίας που έχουν μετατοπιστεί μεταξύ τους. Η δοκιμή σάς επιτρέπει να βρείτε επαναλαμβανόμενες περιοχές σε μια ακολουθία.
Υπάρχουν ειδικά κιτ που περιλαμβάνουν δεκάδες παρόμοιες δοκιμές:
NIST - χρησιμοποιείται στον διαγωνισμό AES για την αξιολόγηση αλγορίθμων κρυπτογράφησης.
Το DIEHARD είναι ένα από τα πιο αυστηρά σετ που υπάρχουν.

Αλγόριθμοι PRNG

Οποιαδήποτε ακολουθία που δημιουργείται σύμφωνα με έναν αυστηρά καθορισμένο αλγόριθμο δεν μπορεί να θεωρηθεί πραγματικά τυχαία, επομένως, όταν μιλάμε για αλγοριθμικές γεννήτριες, χρησιμοποιούν τον όρο ψευδοτυχαίοακολουθία. Οποιαδήποτε γεννήτρια ψευδοτυχαίων αριθμών (PRNG) θα μπει σε βρόχο αργά ή γρήγορα, το άλλο πράγμα είναι ότι αυτό το "καθυστέρημα" μπορεί να έρθει σε λίγα χιλιοστά του δευτερολέπτου ή ίσως σε λίγα χρόνια. Η διάρκεια του κύκλου εξαρτάται από το μέγεθος της εσωτερικής κατάστασης της γεννήτριας N (στην πραγματικότητα, αυτή είναι η ποσότητα μνήμης που χρειάζεται η γεννήτρια) και κυμαίνεται από 2 (N/2) έως 2 N bit.
Έχει εφευρεθεί μια τεράστια ποικιλία αλγορίθμων PRNG, αλλά δεν είναι όλοι βολικοί για εφαρμογή σε μικροελεγκτές. Είμαστε πολύ περιορισμένοι σε ταχύτητα και διαθέσιμη μνήμη· πολλοί ελεγκτές δεν υποστηρίζουν πραγματικές αριθμητικές ή ακόμα και οδηγίες πολλαπλασιασμού. Έχοντας υπόψη αυτούς τους περιορισμούς, ας δούμε μερικούς γνωστούς αλγόριθμους.
Γραμμική σύμφωνη μέθοδος
Το επόμενο μέλος της ακολουθίας υπολογίζεται χρησιμοποιώντας τον τύπο
X i+1 = (aX i + c) mod m
Αριθμός Μορίζει τη μέγιστη περίοδο της ακολουθίας, ακέραιους αριθμούς έναΚαι ντο- «μαγικοί» συντελεστές. Αριθμός ΜΕίναι λογικό να επιλέξετε ίση με ισχύ δύο· σε αυτήν την περίπτωση, η λειτουργία μετατροπής modulo περιορίζεται στην απόρριψη των πιο σημαντικών bits. Για να επιτευχθεί η μέγιστη περίοδος, πρέπει να πληρούνται οι ακόλουθες προϋποθέσεις:
- ντοκαι το m πρέπει να είναι σχετικά πρώτος,
- Α'1πρέπει να είναι πολλαπλάσιο Πγια όλους τους πρωταρχικούς παράγοντες Παριθμοί Μ,
- Αν Μείναι πολλαπλάσιο του 4 (και στην περίπτωσή μας θα είναι πολλαπλάσιο), τότε Α'1πρέπει να είναι πολλαπλάσιο του 4.
Υπάρχει μια ακόμη λεπτότητα: μόνο τα πιο σημαντικά bits της μεταβλητής κατάστασης X πρέπει να λαμβάνονται ως αποτέλεσμα, καθώς για τα χαμηλότερα bit οι στατιστικές παράμετροι της τυχαιότητας είναι πολύ χειρότερες. Ο γραμμικός σύμφωνος αλγόριθμος εφαρμόζεται συνήθως ως τυπική rand() σε πολλές βιβλιοθήκες.

Πλεονεκτήματα:

  • τη μέγιστη δυνατή περίοδο για ένα δεδομένο μέγεθος της μεταβλητής κατάστασης·
  • αρκετά γρήγορα;
  • συχνά ήδη υλοποιείται στη βιβλιοθήκη του μεταγλωττιστή.
Μειονεκτήματα:
  • απαιτείται μια λειτουργία πολλαπλασιασμού.
  • δεν είναι όλα τα bit εξίσου τυχαία.
Περίληψη:ένας γρήγορος και απλός αλγόριθμος για όχι πολύ απαιτητικές εφαρμογές.
Μέθοδος Fibonacci με καθυστερήσεις
Αυτός ο αλγόριθμος χρησιμοποιεί τη σχέση
X i = X i-a - X i-b,
πού είναι η μεταβλητή κατάσταση Χ- ανυπόγραφος ακέραιος αριθμός. Τιμές καθυστέρησης έναΚαι σιΔεν λαμβάνονται οποιεσδήποτε, αλλά αυστηρά καθορισμένες· για να επιτευχθεί η μέγιστη ποιότητα, συνιστώνται ζεύγη (17,5), (55,24) ή (97,33). Όσο μεγαλύτερη είναι η καθυστέρηση, τόσο μεγαλύτερη είναι η περίοδος και τόσο καλύτερες είναι οι φασματικές ιδιότητες της ακολουθίας. Από την άλλη πλευρά, για να λειτουργήσει η γεννήτρια, είναι απαραίτητο να αποθηκεύσετε max(a,b) προηγούμενων αριθμών, κάτι που δεν είναι πάντα αποδεκτό. Επίσης, για να τρέξετε τη γεννήτρια χρειάζεστε max(a,b) αριθμούς, οι οποίοι συνήθως λαμβάνονται χρησιμοποιώντας ένα απλούστερο PRNG.

Πλεονεκτήματα:

  • δεν απαιτεί λειτουργίες πολλαπλασιασμού.
  • όλα τα bit ενός τυχαίου αριθμού είναι ισοδύναμα σε στατιστικές ιδιότητες.
Μειονεκτήματα:
  • απαιτεί μεγάλη ποσότητα μνήμης.
  • απαιτεί μια μεγάλη σειρά αριθμών για να εκτελεστεί.
Περίληψη:ένας αλγόριθμος πολύ υψηλής ποιότητας, αλλά με ένταση πόρων.
Γραμμική ανατροφοδότηση Shift Register


Η μεταβλητή κατάστασης αποθηκεύεται σε έναν καταχωρητή μήκους N. Η δημιουργία της επόμενης κατάστασης περιλαμβάνει δύο βήματα:
  1. Η τιμή του bit υπολογίζεται C = X i1 xor X i2 xor… X ik, όπου i1, i2…ik- καταχωρήστε αριθμούς bit, που καλούνται λυγίζει.
  2. Ο καταχωρητής μετατοπίζεται 1 bit προς τα δεξιά, το πιο αριστερό bit παίρνει την τιμή ΜΕ.
Η έξοδος της γεννήτριας είναι το δεξιότερο (ή το πιο αριστερό, ή οποιοδήποτε άλλο) bit του καταχωρητή, δηλαδή, η ψευδοτυχαία ακολουθία δημιουργείται ένα bit ανά επανάληψη. Με σωστά επιλεγμένους αριθμούς βρύσης, η περίοδος της γεννήτριας θα είναι 2 N - 1. «Μείον ένα», καθώς υπάρχει απαγορευμένη μηδενική κατάσταση του μητρώου. Αριθμοί υποκαταστημάτων για Ναπό 3 έως 168 μπορείτε να βρείτε σε αυτό το έγγραφο.
Εκτός από τη διαμόρφωση που περιγράφεται παραπάνω, η οποία, παρεμπιπτόντως, ονομάζεται διαμόρφωση Fibonacci (δεν πρέπει να συγχέεται με την ομώνυμη μέθοδο PRNG!), υπάρχει το λεγόμενο. Διαμόρφωση Galois.


Αντί να χρησιμοποιεί το άθροισμα των bit στην ακολουθία tap για να δημιουργήσει ένα νέο πιο αριστερό bit, XORs κάθε bit στην ακολουθία tap με το δεξιότερο bit και, στη συνέχεια, περιστρέφει ολόκληρο τον καταχωρητή προς τα δεξιά. Αυτό το σχήμα είναι πιο δύσκολο να κατανοηθεί, αλλά πιο εύκολο να εφαρμοστεί, καθώς όλες οι λειτουργίες XOR μπορούν να εκτελεστούν ταυτόχρονα. Όσον αφορά τη διάρκεια περιόδου και την ποιότητα των ψευδοτυχαίων αριθμών, τα σχήματα Fibonacci και Galois είναι ισοδύναμα.

Πλεονεκτήματα:

  • πολύ απλή υλοποίηση, δεν απαιτεί καν αριθμητική, μόνο πράξεις και μετατοπίσεις bit.
  • πολύ γρήγορος αλγόριθμος (ειδικά το σχήμα Galois).
  • καλές στατιστικές ιδιότητες.
Μειονεκτήματα:
  • πρέπει να ελέγξετε την αρχική τιμή για ανισότητα στο μηδέν.
Περίληψη:πολύ γρήγορος και αρκετά υψηλής ποιότητας αλγόριθμος.
Κρυπτοστεγανοί αλγόριθμοι
Για χρήση στην κρυπτογραφία, τα PRNG έχουν μια ακόμη βασική απαίτηση: μη αναστρεψιμότητα. Όλοι οι αλγόριθμοι που αναφέρονται παραπάνω δεν έχουν αυτήν την ιδιότητα: γνωρίζοντας πολλές τιμές εξόδου του PRNG, μπορείτε, λύνοντας ένα απλό σύστημα εξισώσεων, να βρείτε τις παραμέτρους του αλγορίθμου (οι ίδιες «μαγικές» σταθερές α, β, γκαι τα λοιπά). Και γνωρίζοντας τις παραμέτρους, μπορείτε να αναπαράγετε ολόκληρη την ψευδοτυχαία ακολουθία.
Οποιοσδήποτε επαρκώς ισχυρός κρυπτογράφηση μπλοκ μπορεί να χρησιμοποιηθεί ως κρυπτογραφικά ισχυρός αλγόριθμος PRNG. Επιλέγοντας ένα μυστικό κλειδί, μπορείτε να αποκτήσετε μπλοκ ψευδοτυχαίων αριθμών εφαρμόζοντας τον αλγόριθμο σε διαδοχικούς φυσικούς αριθμούς. Για έναν κρυπτογράφηση μπλοκ N-bit, η περίοδος δεν θα είναι μεγαλύτερη από 2 N. Η ασφάλεια ενός τέτοιου συστήματος εξαρτάται εξ ολοκλήρου από το απόρρητο του κλειδιού.
Όλοι οι σύγχρονοι κρυπτογραφικοί αλγόριθμοι ελέγχονται για χρήση ως PRNG, δηλαδή, χρησιμοποιώντας έναν πιστοποιημένο αλγόριθμο, δεν χρειάζεται να ενδιαφέρεστε ιδιαίτερα για τις στατιστικές και φασματικές ιδιότητες της ροής εξόδου. Χρειάζεται μόνο να ανησυχείτε για την υπολογιστική «λαιμαργία» των αλγορίθμων κρυπτογράφησης. Εάν χρειάζεται να εκτελέσετε μεγάλο αριθμό λειτουργιών κρυπτογράφησης, είναι λογικό να επιλέξετε έναν ελεγκτή με κρυπτογραφικά μπλοκ υλικού. Συχνά, τέτοιοι ελεγκτές έχουν επίσης ένα πολύ καλό υλικό PRNG, ανθεκτικό στην κρυπτογράφηση.

Πηγές εντροπίας

Όπως αναφέρθηκε ήδη, χρησιμοποιώντας μόνο ντετερμινιστικούς αλγόριθμους, είναι αδύνατο να δημιουργηθεί ένας πραγματικά τυχαίος αριθμός. Επομένως, συνήθως χρησιμοποιείται ένας συνδυασμός PRNG + εξωτερικό πηγή εντροπίας. Η πηγή εντροπίας χρησιμοποιείται για τον καθορισμό της αρχικής τιμής για το PRNG και η αποστολή του τελευταίου είναι να διασφαλίσει τη φασματική και στατιστική καθαρότητα της ακολουθίας. Τι μπορεί να χρησιμοποιηθεί ως πηγή εντροπίας; Ναι, σχεδόν οτιδήποτε.
Δραστηριότητα χρήστη
Εάν η συσκευή αλληλεπιδρά με τον χρήστη με οποιονδήποτε τρόπο, μια αρκετά καλή λύση θα ήταν να χρησιμοποιηθεί ο ίδιος ο χρήστης ως πηγή εντροπίας. Για παράδειγμα, ο χρόνος πατήματος ενός κουμπιού, μετρημένος με ακρίβεια μικροδευτερόλεπτου (ή μάλλον, τα λιγότερο σημαντικά ψηφία του), είναι εντελώς απρόβλεπτος. Ωστόσο, συχνά η συσκευή πρέπει να λειτουργεί αυτόνομα, πράγμα που σημαίνει ότι στερούμαστε αυτό το υπέροχο κανάλι πληροφοριών.
Μετατροπέας αναλογικού σε ψηφιακό
Πολλοί ελεγκτές έχουν ενσωματωμένους ADC. Και σε πολλά χειριστήρια είναι πολύ μέτριας ποιότητας, φτιαγμένα απλά για να είναι. Τα δυαδικά ψηφία χαμηλής τάξης του αποτελέσματος ADC περιέχουν σχεδόν πάντα σημαντικό θόρυβο, ακόμη και κατά τη μέτρηση της τάσης DC. Αυτό μπορεί να χρησιμοποιηθεί: συνδέστε την είσοδο ADC στην τάση τροφοδοσίας μέσω ενός διαιρέτη, κάντε μερικές δεκάδες μετρήσεις, λάβετε τα λιγότερο σημαντικά bits - εδώ έχετε έναν εξαιρετικό τυχαίο αριθμό. Εάν το ADC περιέχει ενσωματωμένο προενισχυτή, ενεργοποιήστε τον, έχει επίσης θόρυβο.
Ασύγχρονες γεννήτριες
Μπορείτε να χρησιμοποιήσετε τη διαφορά στις περιόδους δύο μη συγχρονισμένων γεννητριών ρολογιού. Οι περισσότεροι ελεγκτές περιέχουν, για παράδειγμα, ένα χρονόμετρο παρακολούθησης. Για να αυξηθεί η αξιοπιστία, χρονομετρείται από μια ξεχωριστή γεννήτρια, η οποία σε καμία περίπτωση δεν συνδέεται με το κύριο σήμα ρολογιού. Αρκεί να μετρήσετε τον αριθμό των κύκλων του κύριου σήματος ρολογιού κατά τη διάρκεια μιας περιόδου του χρονοδιακόπτη παρακολούθησης. Εάν επιλέξετε περιόδους έτσι ώστε ο μετρητής να υπερχειλίζει πολλές φορές κατά τη διάρκεια της μέτρησης, μπορείτε να πάρετε έναν αρκετά τυχαίο αριθμό. Το μειονέκτημα αυτής της μεθόδου είναι ότι χρειάζεται πολύς χρόνος, έως και αρκετά δευτερόλεπτα.
Ρολόι πραγματικού χρόνου
Αν το διάγραμμα έχει Ρολόι πραγματικού χρόνου, μπορείτε να χρησιμοποιήσετε τις τρέχουσες αναγνώσεις τους για να αρχικοποιήσετε το PRNG. Για παράδειγμα, μετατρέποντας την τρέχουσα ημερομηνία/ώρα στη μορφή ώρας Unix, παίρνουμε αμέσως 32 bit, τα οποία ποτέδεν θα ξανασυμβεί αν δεν κάνετε μετρήσεις περισσότερες από μία φορές το δευτερόλεπτο. Η χρήση πραγματικού χρόνου παρέχει μοναδικές τιμές, αλλά δεν παρέχει κανένα απρόβλεπτο, επομένως είναι καλύτερο να συνδυάσετε αυτήν τη μέθοδο με άλλες.
Κύκλωμα RC
Εάν ο ελεγκτής δεν διαθέτει περιφερειακές συσκευές εκτός από τις θύρες I/O, μπορείτε να προχωρήσετε ως εξής: ένα από τα πόδια συνδέεται μέσω ενός πυκνωτή στη γείωση και μέσω μιας αντίστασης στην τάση τροφοδοσίας. Εάν οι είσοδοι του ελεγκτή έχουν εσωτερικές αντιστάσεις έλξης, δεν απαιτείται εξωτερική αντίσταση.

Εξάγουμε ένα σήμα "0" σε αυτή τη θύρα - ο πυκνωτής αποφορτίζεται. Αλλάζουμε τη θύρα σε λειτουργία εισόδου - ο πυκνωτής αρχίζει να φορτίζει. Όταν η τάση σε αυτό φτάσει στο κατώφλι, η είσοδος θα αλλάξει από την κατάσταση "0" σε "1". Ο χρόνος φόρτισης εξαρτάται σε μεγάλο βαθμό από πολλούς παράγοντες: τάση τροφοδοσίας, μετατόπιση των παραμέτρων του κυκλώματος RC, αστάθεια κατωφλίου, θερμοκρασία, διαρροές, παρεμβολές. Μετρώντας το με επαρκή ακρίβεια και λαμβάνοντας τα λιγότερο σημαντικά bits, μπορείτε να έχετε καλή τυχαιότητα.
Γεννήτρια θορύβου υλικού
Για πολλές σοβαρές εφαρμογές (κυρίως κρυπτογραφία), απαιτείται μια πιο αξιόπιστη πηγή εντροπίας από αυτές που αναφέρονται παραπάνω. Σε τέτοιες περιπτώσεις, χρησιμοποιούν ψηφιοποίηση του σήματος από μια γεννήτρια θορύβου που βασίζεται σε θερμικά, βολή ή ακόμα και κβαντικά αποτελέσματα. Το στοιχείο θορύβου είναι συνήθως μια ειδική δίοδος ή δίοδος zener, το σήμα από την οποία ενισχύεται και τροφοδοτείται σε έναν συγκριτή που δημιουργεί ένα δυαδικό ρεύμα bit.

Για να διασφαλιστεί ότι το όριο απόκρισης του συγκριτή δεν επηρεάζει τις στατιστικές ιδιότητες του λαμβανόμενου σήματος, χρησιμοποιούνται δύο γεννήτριες θορύβου που λειτουργούν σε έναν συγκριτή:

συμπέρασμα

Τέλος, θα σας πω μια ιστορία από τη ζωή μου. Ξεκίνησε με μια άλλη ερώτηση που έγινε στο φόρουμ: "πώς μπορώ να δημιουργήσω έναν τυχαίο αριθμό στον ελεγκτή;" Ο συγγραφέας της ερώτησης εξήγησε ότι ως πρόγραμμα μαθημάτων κατασκευάζει μια συσκευή που μιμείται τη ρίψη ζαριών. Μετά από αρκετές ανεπιτυχείς προσπάθειες κατανόησης των αλγορίθμων, ο εκκινητής θεμάτων μοιράστηκε τη λύση του: απλώς έριξε ένα πραγματικό ζάρι 1000 φορές και γέμισε όλη την ελεύθερη μνήμη του ελεγκτή με τους αριθμούς που προέκυψαν. Η γεννήτρια πέρασε έξοχα όλα τα τεστ «τυχαιότητας», δεδομένου ότι κατά τη διάρκεια της επίδειξης εξαντλούσε λιγότερο από το ένα τρίτο του «αποθεματικού» της.
Επομένως, μια τέτοια λύση έχει επίσης δικαίωμα στη ζωή, ειδικά εάν επιβάλλονται πολύ αυστηρές απαιτήσεις για την τυχαιότητα των αριθμών, αλλά δεν απαιτούνται πολύ συχνά. Με τις τιμές της μνήμης να πέφτουν κατακόρυφα, ίσως είναι συνετό να εξοπλίσετε μια συσκευή με ένα "απόθεμα χάους" που θα διαρκέσει όλη τη διάρκεια ζωής της συσκευής.
Ευχαριστώ για την προσοχή!

UPD1:Όπως σωστά σημειώθηκε στα σχόλια, εάν σχεδιάζεται επίθεση στο RNG και ο εισβολέας έχει πρόσβαση υλικού στη συσκευή, οι εξωτερικές πηγές εντροπίας πρέπει να χρησιμοποιούνται με μεγάλη προσοχή, καθώς δεν είναι πολύ δύσκολο να αντικατασταθεί το σήμα από εξωτερική πηγή. Θα πρέπει να χρησιμοποιούνται εσωτερικές πηγές, εκτός από εξωτερικές.
Είναι επίσης καλή ιδέα να συσσωρεύετε εντροπία σε όλο τον ελεύθερο χρόνο σας και να τη χρησιμοποιείτε όταν χρειάζεται να δημιουργήσετε τον επόμενο τυχαίο αριθμό. Συνήθως σε τέτοιες περιπτώσεις τα λεγόμενα Πισίνα εντροπίας- ένας πίνακας στον οποίο εκτελείται περιοδικά μία από τις συναρτήσεις PRNG και στον οποίο αναμιγνύονται συνεχώς δεδομένα από πηγές εντροπίας.

UPD2:Σε πολλές περιπτώσεις, είναι χρήσιμο να αποθηκεύσετε τα περιεχόμενα της πισίνας Entropy (συγγνώμη, δεν γνωρίζω την κανονική ρωσική μετάφραση) στην EEPROM, έτσι ώστε μετά την απενεργοποίηση και την ενεργοποίηση της συσκευής να μην τα συγκεντρώνει ξανά. Αυτό σχετίζεται, πρώτα απ 'όλα, με τη λήψη εντροπίας χρησιμοποιώντας τη μέθοδο των ασύγχρονων γεννητριών: κάτω από επαρκώς σταθερές συνθήκες, η ίδια ακολουθία μπορεί να δημιουργηθεί μετά από κάθε ενεργοποίηση.
Εάν αναμένεται επίθεση, λάβετε προφυλάξεις κατά της παραβίασης της EEPROM. Εάν το επιτρέπει ο ελεγκτής, μπλοκάρετε την ανάγνωση/διαγραφή/εγγραφή χρησιμοποιώντας bits κλειδώματος και όταν το ενεργοποιείτε, παρακολουθήστε την ακεραιότητα του EEPROM, τουλάχιστον χρησιμοποιώντας απλά αθροίσματα ελέγχου.

Ετικέτες:

  • RNG
  • gpsch
  • μικροελεγκτές
  • αλγόριθμους
Προσθέστε ετικέτες

Κατά τον προγραμματισμό του Arduino, υπάρχουν φορές που χρειάζεται να λάβετε έναν αριθμό που δεν θα είναι γνωστός εκ των προτέρων ούτε στον προγραμματιστή που γράφει το σκίτσο ούτε στον χρήστη που θα χρησιμοποιήσει το Arduino με ένα τέτοιο πρόγραμμα. Σε αυτήν την περίπτωση, μια γεννήτρια τυχαίων (ή μάλλον ψευδοτυχαίων) αριθμών έρχεται στη διάσωση.



Για να ενεργοποιήσετε αυτήν τη γεννήτρια, απλώς χρησιμοποιήστε τις συναρτήσεις random() ή randomSeed(). Αυτό το υλικό θα σας δείξει πώς να εργαστείτε με αυτές τις συναρτήσεις, καθώς και πώς να απαλλαγείτε από την ψευδοτυχαιότητα κατά τη δημιουργία αριθμών.


Γενικά, μια γεννήτρια ψευδοτυχαίων αριθμών προσομοιώνει τη χαοτική ή τυχαία εμφάνιση αριθμών, αλλά στην πραγματικότητα, αν αναλύσετε μια σειρά από αυτούς τους αριθμούς για μια αρκετά μεγάλη περίοδο, μπορείτε να παρατηρήσετε ένα συγκεκριμένο μοτίβο.


Έτσι, η τυχαία συνάρτηση για τη δημιουργία ψευδοτυχαίων αριθμών μπορεί να έχει έως και δύο παραμέτρους και γράφεται ως τυχαία(max) ή τυχαία(min, max). Εδώ, η παράμετρος max, η οποία είναι υποχρεωτική, ορίζει το ανώτερο όριο του εύρους για τη δημιουργία ψευδοτυχαίων αριθμών. Χρησιμοποιώντας την πρόσθετη παράμετρο min, μπορείτε να ορίσετε το κατώτερο όριο του εύρους. Ως αποτέλεσμα, η συνάρτηση θα επιστρέψει κάποιο ψευδοτυχαίο αριθμό στο εύρος από min έως max-1.


Είναι σημαντικό να κατανοήσουμε ότι όταν χρησιμοποιείτε τη συνάρτηση random(), θα δημιουργείται η ίδια ακριβώς λίστα ψευδοτυχαίων αριθμών κάθε φορά. Για παράδειγμα, αν φτιάξετε έναν κουλοχέρη και την πρώτη φορά που πατήσετε τη λαβή, δείχνει έναν νικηφόρο συνδυασμό, τότε μπορείτε να είστε σίγουροι ότι εάν επαναφέρετε το Arduino και πατήσετε ξανά τη λαβή, αυτός ο κουλοχέρης θα εμφανίσει τον ίδιο νικητήριο συνδυασμό . Πράγματι, δεν είναι εύκολο να υλοποιήσετε μια παιχνιδομηχανή με εντελώς τυχαία παραγωγή αριθμών στο Arduino, όπως, για παράδειγμα, εφαρμόζεται σε μηχανές τυχερών παιχνιδιών www.igrovye-apparati-vulcan.com/, αλλά μπορείτε να λύσετε εν μέρει το πρόβλημα χρησιμοποιώντας το randomSeed () λειτουργία.


Αυτή η συνάρτηση παίρνει μια τιμή (όπως έναν ακέραιο) και χρησιμοποιεί τον αριθμό για να τροποποιήσει την τυχαία λίστα που δημιουργείται από τη συνάρτηση random(). βρόχος. Αλλά ακόμα και τότε, το πρόβλημα είναι ότι παρόλο που η ακολουθία τυχαίων αριθμών θα είναι διαφορετική όταν χρησιμοποιείται η συνάρτηση randomSeed(), θα εξακολουθεί να είναι η ίδια κάθε φορά που εκτελείται το σκίτσο.


Η μόνη λύση σε αυτή την περίπτωση μπορεί να είναι η χρήση αναλογικών περιφερειακών (ADC) και της αντίστοιχης συνάρτησης analogRead(). Εάν η αναλογική είσοδος δεν είναι συνδεδεμένη με τίποτα, δηλαδή αφήνεται "κρεμασμένη" στον αέρα, τότε χάρη στον θόρυβο σε αυτή τη γραμμή μπορείτε να λάβετε πραγματικά τυχαίους αριθμούς. Στη συνέχεια, στη ρύθμιση ρύθμισης μπορείτε να γράψετε randomSeed(analogRead(A0)). Με την προϋπόθεση ότι η αναλογική θύρα A0 δεν είναι συνδεδεμένη πουθενά.

Χρόνος και τυχαιότητα. Αντίδραση

Αυτή τη φορά θα μάθουμε ποιες είναι οι «Τυχαίες» τιμές και επίσης θα μάθουμε πώς να δουλεύουμε με τον χρόνο.

Θα χρειαστούμε:

  • Κουμπί τακτ
  • Τρίζων
  • Καλώδια σύνδεσης "MALE-MALE"

Αντίδραση

Το καθήκον μας για σήμερα είναι να συγκεντρώσουμε ένα διάγραμμα που μας επιτρέπει να μάθουμε την ταχύτητα της αντίδρασής μας.

Όταν πατάτε το αριστερό κουμπί, ακούγεται ένα σήμα μετά από μια «τυχαία» ώρα. Και όταν πατήσετε το δεξί κουμπί, σημειώνεται πόσος χρόνος έχει περάσει από το τρίξιμο μέχρι το πάτημα του δεξιού κουμπιού.

Όσοι είναι επιδέξιοι το δοκιμάζουν μόνοι τους, και βλέπουμε το διάγραμμα.

#define BUZ 8 #define START 9 #define STOP 7 int time; //Μεταβλητή για συγχρονισμό void setup() ( Serial. start(9600); pinMode(START, INPUT_PULLUP); pinMode(STOP, INPUT_PULLUP); pinMode(BUZ, OUTPUT); ) void loop() (if(digitalRead(START) == 0) // Όταν πατάτε το κουμπί START.. ( int start_time = millis(); // Θυμηθείτε τον χρόνο πατήματος = start_time; // Γράψτε τον σε μια καθολική μεταβλητή. int Rand = random(0, 4000 ); // Ας δημιουργήσουμε έναν "τυχαίο" χρόνο καθυστέρησης = χρόνο + Rand; //Προσθήκη της καθυστέρησης χρόνου καθυστέρησης (Rand); //Περιμένετε για τόνο (BUZ, 3000, 500); //Beep! ) if(digitalRead( STOP) == 0 && digitalRead( START) == 1) // Όταν πατάτε το κουμπί STOP... ( int stop_time = millis(); // Θυμηθείτε το stop time. time = stop_time - time; // Υπολογίστε το διαφορά ώρας. Serial.println("Ώρα: "); // Έξοδος της ώρας σε Serial. Serial.println(time); delay(1000); ) ) // Πριν από τη δεύτερη προσπάθεια, πατήστε ξανά το κουμπί START.

Εξηγήσεις

ενθ χρόνος; Στις μεταβλητές (όχι όλες), όταν τις δηλώνουν, δεν χρειάζεται να δίνεται καμία τιμή. Χρησιμοποιήσαμε αυτή τη μεταβλητή για να συνδέσουμε δύο προτάσεις if.

Στη C++, οι μεταβλητές που δηλώνονται μέσα σε έναν βρόχο δεν θα είναι προσβάσιμες σε άλλους βρόχους, καθώς έχουν αποτέλεσμα μόνο εντός αυτού του βρόχου. Αυτό γίνεται για την αποφυγή σφαλμάτων προγραμματισμού. Όταν μεγαλώσει ο κώδικας του προγράμματος, θα καταλάβετε για τι πράγμα μιλάω.

Για να κάνετε μια μεταβλητή διαθέσιμη σε πολλές δηλώσεις, πρέπει να την κάνετε καθολική. Εκείνοι. Δηλώστε μια μεταβλητή εκτός συναρτήσεων.

millis();Επιστρέφει τον αριθμό των χιλιοστών του δευτερολέπτου που έχουν περάσει από την έναρξη του προγράμματος.

Το χρειαζόμαστε για να μετρήσουμε το χρόνο που πέρασε από το σήμα που δίνεται μέχρι το πάτημα του κουμπιού.

τυχαίος(min,Μέγιστη);Αυτή είναι μια γεννήτρια τυχαίων αριθμών. Παίρνει δύο τιμές. Δημιουργεί έναν αριθμό στο εύρος από το ελάχιστο έως το μέγιστο.

«Τυχαίοι» αριθμοί επειδή είναι μια συγκεκριμένη ακολουθία τιμών. Πολύ μεγάλο, αλλά το ίδιο. Για να λάβετε διαφορετικές ακολουθίες, θα πρέπει να χρησιμοποιήσετε ΤυχαίοςΣπόρος();

Αυτή η συνάρτηση αρχικοποιεί τη γεννήτρια. Και αν ορίσουμε την παράμετρο σε τυχαία, τότε θα πάρουμε τις ακολουθίες που χρειαζόμαστε. Η σειρά θα είναι η ίδια εάν η παράμετρος είναι σταθερή.

συμπέρασμα

Τώρα μπορείτε να εκπαιδεύσετε την αντίδρασή σας χρησιμοποιώντας μια συσκευή που φτιάξατε μόνοι σας. Ή μπορείτε να συνεχίσετε να μελετάτε περαιτέρω.

Κατάλογος ραδιοστοιχείων

Ονομασία Τύπος Ονομασία Ποσότητα ΣημείωσηΚατάστημαΤο σημειωματάριό μου
Πλακέτα Arduino

Arduino Uno

1 Στο σημειωματάριο
Ψωμί σανίδαBreadboard-μισό1 Στο σημειωματάριο
ΠιεζοπομπόςΠαθητικός1 Στο σημειωματάριο
Κουμπί τακτΧωρίς κλειδαριά2 Στο σημειωματάριο
Καλώδια σύνδεσης«Παππά-Μπαμπά»1
mob_info