In diesem Artikel erfahren Sie alles über die babylonische Bibliothek und vor allem darüber, wie Sie sie neu erstellen können, und zwar über jede Bibliothek.
Beginnen wir mit den Zitaten aus der
babylonischen Bibliothek von
Luis Borges .
Zitat„Das Universum - manche nennen es die Bibliothek - besteht aus einer riesigen, möglicherweise unendlichen Anzahl sechseckiger Galerien mit breiten Lüftungskammern, die von niedrigen Schienen umgeben sind. Von jedem Sechseck sind zwei obere und zwei untere Stockwerke sichtbar - bis ins Unendliche. “
„Eine Bibliothek ist eine Kugel, deren genaues Zentrum sich in einem der Sechsecke befindet und deren Oberfläche nicht zugänglich ist. An jeder Wand jedes Sechsecks befinden sich fünf Regale, an jedem Regal befinden sich zweiunddreißig Bücher des gleichen Formats, jedes Buch hat vierhundertzehn Seiten, jede Seite hat vierzig Zeilen, jede Zeile enthält ungefähr achtzig schwarze Buchstaben. Auf dem Buchrücken befinden sich Buchstaben, die jedoch nicht definieren oder vorhersagen, was auf den Seiten steht. Ich weiß, diese Diskrepanz schien einst mysteriös. “
Wenn Sie ein zufälliges Sechseck betreten, an eine Wand gehen, in ein Regal schauen und das Buch nehmen, das Ihnen am besten gefällt, sind Sie höchstwahrscheinlich verärgert. Immerhin haben Sie erwartet, den Sinn des Lebens dort herauszufinden, aber Sie haben einige seltsame Charaktere gesehen. Aber reg dich nicht so schnell auf! Die meisten Bücher sind bedeutungslos, da sie eine kombinatorische Suche aller möglichen Varianten von fünfundzwanzig Zeichen darstellen (
es ist dieses Alphabet, das Borges in seiner Bibliothek verwendet hat, aber dann wird der Leser herausfinden, dass es eine beliebige Anzahl von Zeichen in der Bibliothek geben kann ). Das Hauptgesetz der Bibliothek ist, dass es keine zwei absolut identischen Bücher gibt, dementsprechend ist ihre Anzahl begrenzt, und die Bibliothek wird auch eines Tages enden. Borges glaubte, dass die Bibliothek regelmäßig ist:
Zitat„Vielleicht täuschen mich Angst und Alter, aber ich denke, dass die Menschheit - die einzige - vom Aussterben bedroht ist und die Bibliothek überleben wird: beleuchtet, unbewohnt, unendlich, absolut bewegungslos, voller kostbarer Bände, nutzlos, unbestechlich, mysteriös. Ich habe gerade endlos geschrieben. Ich habe dieses Wort nicht aus Liebe zur Rhetorik gesetzt; Ich denke, es ist logisch anzunehmen, dass die Welt endlos ist. Diejenigen, die es für begrenzt halten, geben zu, dass irgendwo in der Ferne Korridore, Treppen und Sechsecke aus einem unbekannten Grund enden können - eine solche Annahme ist absurd. Wer es sich grenzenlos vorstellt, vergisst, dass die Anzahl der möglichen Bücher begrenzt ist. Ich wage es, eine solche Lösung für dieses uralte Problem vorzuschlagen: Die Bibliothek ist grenzenlos und regelmäßig. Wenn der ewige Wanderer eine Reise in eine beliebige Richtung antreten würde, könnte er nach Jahrhunderten überprüfen, ob dieselben Bücher in demselben Durcheinander wiederholt werden (was, wenn es wiederholt wird, zu Ordnung - Ordnung wird). Diese anmutige Hoffnung erhellt meine Einsamkeit. “
Im Vergleich zu Unsinn gibt es nur sehr wenige Bücher, deren Inhalt eine Person zumindest irgendwie verstehen kann, aber dies ändert nichts an der Tatsache, dass die Bibliothek alle Texte enthält, die von einer Person erfunden wurden und jemals erfunden werden. Außerdem sind Sie von Kindheit an daran gewöhnt, einige Symbolsequenzen als sinnvoll zu betrachten, während andere dies nicht tun. Tatsächlich gibt es im Kontext der Bibliothek keinen Unterschied zwischen ihnen. Aber was Sinn macht, hat einen viel geringeren Prozentsatz, und wir nennen es Sprache. Dies ist ein Kommunikationsmittel zwischen Menschen. Jede Sprache enthält nur wenige Zehntausende von Wörtern, von denen wir 70% der Stärke kennen. Daher stellt sich heraus, dass wir den größten Teil der kombinatorischen Suche nach Büchern nicht interpretieren können. Und jemand leidet an
Apophenie und sieht selbst in zufälligen Zeichensätzen versteckte Bedeutungen. Aber das ist eine gute Idee für die
Steganographie ! Nun, ich werde dieses Thema weiterhin in den Kommentaren diskutieren.
Bevor Sie mit der Implementierung dieser Bibliothek fortfahren, werde ich Sie mit einer interessanten Tatsache überraschen: Wenn Sie die babylonische Bibliothek von Louis Borges neu erstellen möchten, werden Sie keinen Erfolg haben, da ihre Volumina das Volumen des sichtbaren Universums 10 ^ 611338 (!) Mal überschreiten. Und darüber, was in noch größeren Bibliotheken passieren wird, habe ich sogar Angst zu denken.
Bibliotheksimplementierung
Modulbeschreibung
Unsere kleine Einführung ist vorbei. Aber es ist nicht ohne Bedeutung: Jetzt verstehen Sie, wie die babylonische Bibliothek aussieht, und das Lesen wird nur interessanter sein. Aber ich werde von der ursprünglichen Idee wegkommen, ich wollte eine "universelle" Bibliothek erstellen, die später besprochen wird. Ich werde in JavaScript unter Node.js schreiben. Was sollte die Bibliothek tun können?
- Finden Sie schnell den gewünschten Text und zeigen Sie seine Position in der Bibliothek an
- Definieren Sie einen Buchtitel
- Finden Sie schnell ein Buch mit dem richtigen Titel
Zusätzlich sollte es universell sein, d.h. Jeder der Bibliotheksparameter kann geändert werden, wenn ich möchte. Nun, ich denke, ich werde zuerst den gesamten Code des Moduls zeigen, wir werden ihn detailliert analysieren, sehen, wie er funktioniert, und ich werde ein paar Worte sagen.
Github-RepositoryDie Hauptdatei ist index.js, die gesamte Logik der Bibliothek wird dort beschrieben, ich werde den Inhalt dieser Datei erklären.
let sha512 = require(`js-sha512`);
Wir verbinden das Modul, das den
sha512- Hashing-
Algorithmus implementiert. Es mag Ihnen seltsam erscheinen, aber es wird uns trotzdem nützlich sein.
Was ist die Ausgabe unseres Moduls? Es gibt eine Funktion zurück, ein Aufruf, der ein Bibliotheksobjekt mit allen erforderlichen Methoden zurückgibt. Wir könnten es sofort zurückgeben, aber dann wäre die Verwaltung der Bibliothek nicht so bequem, wenn wir Parameter an die Funktion übergeben und die „benötigte“ Bibliothek erhalten. Auf diese Weise können wir eine „universelle“ Bibliothek erstellen. Da ich versuche, im ES6-Stil zu schreiben, akzeptiert meine Pfeilfunktion ein Objekt als Parameter, das anschließend in die erforderlichen Variablen zerlegt wird:
module.exports = ({ lengthOfPage = 4819, lengthOfTitle = 31, digs = '0123456789abcdefghijklmnopqrstuvwxyz', alphabet = ', .', wall = 5, shelf = 7, volume = 31, page = 421, } = {}) => {
Lassen Sie uns nun die Parameter durchgehen. Als numerische Standardparameter habe ich mich für Primzahlen entschieden, weil es mir interessanter erschien.
- lengthOfPage - Anzahl, Anzahl der Zeichen auf einer Seite. Der Standardwert ist 4819. Wenn wir diese Zahl berücksichtigen, erhalten wir 61 und 79. 61 Zeilen mit 79 Zeichen oder umgekehrt, aber ich bevorzuge die erste Option.
- lengthOfTitle - Anzahl, Anzahl der Zeichen im Titel des Buchtitels .
- digs - eine Zeichenfolge, mögliche Ziffern einer Zahl mit einer Basis, die der Länge dieser Zeichenfolge entspricht. Wofür ist diese Nummer? Es enthält die Nummer (Kennung) des Sechsecks, zu dem wir gehen möchten. Standardmäßig ist es Kleinbuchstaben Latein und die Zahlen 0-9. Der größte Teil des Textes wird hier codiert, es handelt sich also um eine große Zahl - mehrere tausend Bit (abhängig von der Anzahl der Zeichen auf der Seite), die jedoch zeichenweise verarbeitet wird.
- Alphabet - die Zeichenfolge, die Zeichen, die wir in der Bibliothek sehen möchten. Es wird mit ihnen gefüllt sein. Damit alles richtig funktioniert, muss die Anzahl der Zeichen im Alphabet gleich der Anzahl der Zeichen in der Zeichenfolge sein, wobei mögliche Ziffern der Nummer das Sechseck identifizieren.
- Wandnummer , maximale Wandnummer, Standard 5
- Regalnummer , maximale Regalnummer , Standard 7
- Volumen - Nummer, maximale Buchnummer, standardmäßig 31
- Seitenzahl , maximale Seitenzahl, Standard 421
Wie Sie sehen können, ähnelt dies ein wenig der echten babylonischen Bibliothek von Luis Borges. Aber ich habe mehr als einmal gesagt, dass wir "universelle" Bibliotheken erstellen werden, die so aussehen können, wie wir sie sehen möchten (daher kann die Hex-Zahl irgendwie anders interpretiert werden, zum Beispiel nur die Kennung eines Ortes, an dem die gewünschte gespeichert ist Informationen). Die babylonische Bibliothek ist nur eine davon. Alle haben jedoch viel gemeinsam - ein Algorithmus ist für ihre Leistung verantwortlich, auf den nun eingegangen wird.
Algorithmen für die Seitensuche und -anzeige
Wenn wir zu einer Adresse gehen, sehen wir den Inhalt der Seite. Wenn wir wieder zur gleichen Adresse gehen, sollte der Inhalt genau der gleiche sein. Diese Eigenschaft von Bibliotheken bietet einen Algorithmus zum Generieren von Pseudozufallszahlen - die
lineare kongruente Methode . Wenn wir ein Zeichen auswählen müssen, um die Adresse oder umgekehrt den Inhalt der Seite zu generieren, hilft es uns, und die Anzahl der Seiten, Regale usw. wird als Körnung verwendet. Die Konfiguration meines PRNG: m = 2 ^ 32 (4294967296), a = 22695477, c = 1. Ich möchte auch hinzufügen, dass in unserer Implementierung nur das Prinzip der Zahlengenerierung von der linearen kongruenten Methode übrig bleibt, der Rest wird geändert. Wir gehen weiter auf die Programmliste:
Code module.exports = ({ lengthOfPage = 4819, lengthOfTitle = 31, digs = '0123456789abcdefghijklmnopqrstuvwxyz', alphabet = ', .', wall = 5, shelf = 7, volume = 31, page = 421, } = {}) => { let seed = 13;
Wie Sie sehen können, ändert sich das PRNG-Korn nach jedem Empfang der Nummer, und die Ergebnisse hängen direkt vom sogenannten Referenzpunkt ab - dem Korn, nach dem uns die Zahlen interessieren. (Wir generieren die Adresse oder erhalten den Inhalt der Seite)
Die
getHash- Funktion hilft uns, einen Referenzpunkt zu generieren. Wir bekommen nur einen Hash von einigen Daten, nehmen 7 Zeichen, übersetzen in ein Dezimalzahlensystem und fertig!
Die
Mod- Funktion verhält sich genauso wie der% -Operator. Wenn die Dividende jedoch <0 ist (solche Situationen sind möglich), gibt die
Mod- Funktion aufgrund der speziellen Struktur eine positive Zahl zurück. Wir benötigen diese, um die Zeichen aus der
Alphabet- Zeichenfolge korrekt auszuwählen, wenn der Inhalt der Seite an der Adresse empfangen wird.
Und das letzte Stück Dessertcode ist das zurückgegebene Bibliotheksobjekt:
Code return { wall, shelf, volume, page, lengthOfPage, lengthOfTitle, search(searchStr) { let wall = `${(Math.random() * this.wall + 1 ^ 0)}`, shelf = `${(Math.random() * this.shelf + 1 ^ 0)}`, volume = pad(`${(Math.random()* this.volume + 1 ^ 0)}`, 2), page = pad(`${(Math.random()* this.page + 1 ^ 0)}`, 3), locHash = getHash(`${wall}${shelf}${volume}${page}`), hex = ``, depth = Math.random() * (this.lengthOfPage - searchStr.length) ^ 0; for (let i = 0; i < depth; i++){ searchStr = alphabet[Math.random() * alphabet.length ^ 0] + searchStr; } seed = locHash; for (let i = 0; i < searchStr.length; i++){ let index = alphabetIndexes[searchStr[i]] || -1, rand = rnd(0, alphabet.length), newIndex = mod(index + parseInt(rand), digs.length), newChar = digs[newIndex]; hex += newChar; } return `${hex}-${wall}-${shelf}-${+volume}-${+page}`; }, searchExactly(text) { const pos = Math.random() * (this.lengthOfPage - text.length) ^ 0; return this.search(`${` `.repeat(pos)}${text}${` `.repeat(this.lengthOfPage - (pos + text.length))}`); }, searchTitle(searchStr) { let wall = `${(Math.random() * this.wall + 1 ^ 0)}`, shelf = `${(Math.random() * this.shelf + 1 ^ 0)}`, volume = pad(`${(Math.random()* this.volume + 1 ^ 0)}`, 2), locHash = getHash(`${wall}${shelf}${volume}`), hex = ``; searchStr = searchStr.substr(0, this.lengthOfTitle); searchStr = searchStr.length == this.lengthOfTitle ? searchStr : `${searchStr}${` `.repeat(this.lengthOfTitle - searchStr.length)}`; seed = locHash; for (let i = 0; i < searchStr.length; i++){ let index = alphabetIndexes[searchStr[i]], rand = rnd(0, alphabet.length), newIndex = mod(index + parseInt(rand), digs.length), newChar = digs[newIndex]; hex += newChar; } return `${hex}-${wall}-${shelf}-${+volume}`; }, getPage(address) { let addressArray = address.split(`-`), hex = addressArray[0], locHash = getHash(`${addressArray[1]}${addressArray[2]}${pad(addressArray[3], 2)}${pad(addressArray[4], 3)}`), result = ``; seed = locHash; for (let i = 0; i < hex.length; i++) { let index = digsIndexes[hex[i]], rand = rnd(0, digs.length), newIndex = mod(index - parseInt(rand), alphabet.length), newChar = alphabet[newIndex]; result += newChar; } seed = getHash(result); while (result.length < this.lengthOfPage) { result += alphabet[parseInt(rnd(0, alphabet.length))]; } return result.substr(result.length - this.lengthOfPage); }, getTitle(address) { let addressArray = address.split(`-`), hex = addressArray[0], locHash = getHash(`${addressArray[1]}${addressArray[2]}${pad(addressArray[3], 2)}`), result = ``; seed = locHash; for (let i = 0; i < hex.length; i++) { let index = digsIndexes[hex[i]], rand = rnd(0, digs.length), newIndex = mod(index - parseInt(rand), alphabet.length), newChar = alphabet[newIndex]; result += newChar; } seed = getHash(result); while (result.length < this.lengthOfTitle) { result += alphabet[parseInt(rnd(0, alphabet.length))]; } return result.substr(result.length - this.lengthOfTitle); } };
Zu Beginn schreiben wir ihm die Eigenschaften der Bibliothek, die ich zuvor beschrieben habe. Sie können sie auch nach dem Aufruf der Hauptfunktion ändern (die im Prinzip als Konstruktor bezeichnet werden kann, aber mein Code ist der Klassenimplementierung der Bibliothek schwach ähnlich, daher beschränke ich mich auf das Wort „main“). Vielleicht ist dieses Verhalten nicht ganz ausreichend, aber flexibel. Gehen Sie nun jede Methode durch.
Suchmethode
search(searchStr) { let wall = `${(Math.random() * this.wall + 1 ^ 0)}`, shelf = `${(Math.random() * this.shelf + 1 ^ 0)}`, volume = pad(`${(Math.random() * this.volume + 1 ^ 0)}`, 2), page = pad(`${(Math.random() * this.page + 1 ^ 0)}`, 3), locHash = getHash(`${wall}${shelf}${volume}${page}`), hex = ``, depth = Math.random() * (this.lengthOfPage - searchStr.length) ^ 0; for (let i = 0; i < depth; i++){ searchStr = alphabet[Math.random() * alphabet.length ^ 0] + searchStr; } seed = locHash; for (let i = 0; i < searchStr.length; i++){ let index = alphabetIndexes[searchStr[i]] || -1, rand = rnd(0, alphabet.length), newIndex = mod(index + parseInt(rand), digs.length), newChar = digs[newIndex]; hex += newChar; } return `${hex}-${wall}-${shelf}-${+volume}-${+page}`; }
Gibt die Adresse der
searchStr- Zeichenfolge in der Bibliothek zurück. Wählen Sie dazu zufällig
Wand, Regal, Volumen und Seite aus .
Volumen und
Seite werden ebenfalls mit Nullen auf die gewünschte Länge aufgefüllt. Verketten Sie sie anschließend zu einer Zeichenfolge, um sie an die Funktion
getHash zu übergeben . Der resultierende
locHash ist der Startpunkt, d.h. das Getreide.
Für eine größere Unvorhersehbarkeit ergänzen wir die
searchStr- Tiefe durch pseudozufällige Zeichen des Alphabets und setzen den
Startwert auf
locHash . In diesem Stadium spielt es keine Rolle, wie wir die Zeile ergänzen. Sie können also das integrierte JavaScript-PRNG verwenden. Dies ist nicht kritisch. Sie können es ganz aufgeben, damit die für uns interessanten Ergebnisse immer ganz oben auf der Seite stehen.
Sie müssen nur noch die Sechseckkennung generieren. Für jedes Zeichen der
searchStr- Zeichenfolge führen
wir den Algorithmus aus:
- Rufen Sie die Nummer des Indexzeichens im Alphabet aus dem Objekt alphabetIndexes ab. Wenn dies nicht der Fall ist, geben Sie -1 zurück. In diesem Fall machen Sie definitiv etwas falsch.
- Generieren Sie mit unserem PRNG einen Pseudozufallszahlen- Rand im Bereich von 0 bis zur Länge des Alphabets.
- Berechnen Sie den neuen Index, der als Summe aus der Nummer des Symbolindex und der Pseudozufallszahl Rand berechnet wird, modulo geteilt durch die Länge der Digs .
- So haben wir die Ziffer des Sechseck-Bezeichners - newChar (aus digs ) erhalten.
- Fügen Sie newChar zum Hex-Bezeichner hex hinzu
Nach Abschluss der
Hex- Generierung geben wir die vollständige Adresse des Ortes zurück, an dem die gewünschte Zeile enthalten ist. Adresskomponenten werden durch einen Bindestrich getrennt.
SearchExactly-Methode
searchExactly(text) { const pos = Math.random() * (this.lengthOfPage - text.length) ^ 0; return this.search(`${` `.repeat(pos)}${text}${` `.repeat(this.lengthOfPage - (pos + text.length))}`); }
Diese Methode macht dasselbe wie die
Suchmethode , füllt jedoch den gesamten freien Speicherplatz (macht die
Suchzeichenfolge searchStr mit einer Länge von
lengthOfPage- Zeichen). Wenn Sie eine solche Seite anzeigen, scheint nichts außer Ihrem Text darauf zu sein.
SearchTitle-Methode
searchTitle(searchStr) { let wall = `${(Math.random() * this.wall + 1 ^ 0)}`, shelf = `${(Math.random() * this.shelf + 1 ^ 0)}`, volume = pad(`${(Math.random()* this.volume + 1 ^ 0)}`, 2), locHash = getHash(`${wall}${shelf}${volume}`), hex = ``; searchStr = searchStr.substr(0, this.lengthOfTitle); searchStr = searchStr.length == this.lengthOfTitle ? searchStr : `${searchStr}${` `.repeat(this.lengthOfTitle - searchStr.length)}`; seed = locHash; for (let i = 0; i < searchStr.length; i++){ let index = alphabetIndexes[searchStr[i]], rand = rnd(0, alphabet.length), newIndex = mod(index + parseInt(rand), digs.length), newChar = digs[newIndex]; hex += newChar; } return `${hex}-${wall}-${shelf}-${+volume}`; }
Die
searchTitle- Methode gibt die Adresse eines Buches mit dem Namen
searchStr zurück . Im Inneren ist es der
Suche sehr ähnlich. Der Unterschied besteht darin, dass wir bei der Berechnung von
locHash die Seite nicht verwenden, um ihren Namen an das Buch zu binden. Es sollte nicht von der Seite abhängen.
searchStr wird auf
lengthOfTitle abgeschnitten und bei Bedarf mit Leerzeichen aufgefüllt. In ähnlicher Weise wird die Sechseckkennung generiert und die empfangene Adresse zurückgegeben. Bitte beachten Sie, dass sich keine Seite darin befindet, wie bei der Suche nach der genauen Adresse eines beliebigen Textes. Wenn Sie also herausfinden möchten, was in dem Buch mit dem von Ihnen geprägten Namen steht, entscheiden Sie sich für die Seite, zu der Sie gehen möchten.
GetPage-Methode
getPage(address) { let addressArray = address.split(`-`), hex = addressArray[0], locHash = getHash(`${addressArray[1]}${addressArray[2]}${pad(addressArray[3], 2)}${pad(addressArray[4], 3)}`), result = ``; seed = locHash; for (let i = 0; i < hex.length; i++) { let index = digsIndexes[hex[i]], rand = rnd(0, digs.length), newIndex = mod(index - parseInt(rand), alphabet.length), newChar = alphabet[newIndex]; result += newChar; } seed = getHash(result); while (result.length < this.lengthOfPage) { result += alphabet[parseInt(rnd(0, alphabet.length))]; } return result.substr(result.length - this.lengthOfPage); }
Das Gegenteil der
Suchmethode . Seine Aufgabe ist es, den Inhalt der Seite an die angegebene Adresse zurückzugeben. Dazu konvertieren wir die Adresse mit dem Trennzeichen "-" in ein Array. Jetzt haben wir eine Reihe von Adresskomponenten: Sechseckkennung, Wand, Regal, Buch, Seite. Wir berechnen
locHash auf die gleiche Weise wie bei der
Suchmethode . Wir erhalten die gleiche Nummer wie beim Generieren der Adresse. Dies bedeutet, dass der PRNG die gleichen Zahlen erzeugt. Dieses Verhalten stellt die Reversibilität unserer Transformationen über den Quelltext sicher. Um dies zu berechnen, führen wir den Algorithmus für jedes Zeichen (de facto ist dies eine Ziffer) der Sechseckkennung durch:
- Wir berechnen den Index in den String Digs . Nehmen Sie es von digsIndexes .
- Mit dem PRNG erzeugen wir einen Pseudozufallszahlen- Rand im Bereich 0 bis zur Basis des Zahlensystems einer großen Zahl, der der Länge der Zeichenfolge entspricht, die die Ziffern dieser schönen Zahl enthält. Alles ist offensichtlich.
- Wir berechnen die Position des Symbols des Quelltextes newIndex als Differenz zwischen Index und Rand , modulo geteilt durch die Länge des Alphabets. Wenn die Differenz negativ ist, ergibt das übliche Divisionsmodulo einen negativen Index, der nicht zu uns passt. Daher verwenden wir eine modifizierte Version der Modulo-Division. (Sie können die Option ausprobieren, den Absolutwert aus der obigen Formel zu übernehmen. Dies löst auch das Problem der negativen Zahlen, aber in der Praxis wurde dies noch nicht getestet.)
- Das Zeichen des Textes der Seite ist newChar , wir erhalten den Index aus dem Alphabet.
- Fügen Sie dem Ergebnis ein Textzeichen hinzu.
Das zu diesem Zeitpunkt erzielte Ergebnis füllt nicht immer die gesamte Seite aus. Daher berechnen wir die neue Körnung aus dem aktuellen Ergebnis und füllen den freien Speicherplatz mit Zeichen aus dem Alphabet. Das PRNG hilft uns bei der Auswahl eines Symbols.
Damit ist die Berechnung des Seiteninhalts abgeschlossen. Wir geben ihn zurück und vergessen nicht, ihn auf die maximale Länge zuzuschneiden. Möglicherweise war die Sechseckkennung in der Eingabeadresse unangemessen groß.
GetTitle-Methode
getTitle(address) { let addressArray = address.split(`-`), hex = addressArray[0], locHash = getHash(`${addressArray[1]}${addressArray[2]}${pad(addressArray[3], 2)}`), result = ``; seed = locHash; for (let i = 0; i < hex.length; i++) { let index = digsIndexes[hex[i]], rand = rnd(0, digs.length), newIndex = mod(index - parseInt(rand), alphabet.length), newChar = alphabet[newIndex]; result += newChar; } seed = getHash(result); while (result.length < this.lengthOfTitle) { result += alphabet[parseInt(rnd(0, alphabet.length))]; } return result.substr(result.length - this.lengthOfTitle); }
Nun, die Geschichte ist dieselbe. Stellen Sie sich vor, Sie lesen die Beschreibung der vorherigen Methode nur, wenn Sie die PRNG-Körner berechnen, berücksichtigen Sie nicht die Seitenzahl und fügen Sie das Ergebnis zur maximalen Länge des
Buchtitels hinzu -
lengthOfTitle .
Testen des Moduls zum Erstellen von Bibliotheken
Nachdem wir das Funktionsprinzip einer babylonischen Bibliothek untersucht haben, ist es Zeit, alles in der Praxis auszuprobieren. Ich werde die Konfiguration so nah wie möglich an der von Louis Borges erstellten verwenden. Wir werden nach einem einfachen Ausdruck "habr.com" suchen:
const libraryofbabel = require(`libraryofbabel`)({ lengthOfPage: 3200, alphabet: `abcdefghijklmnopqrstuvwxyz, .`,
Führen Sie das Ergebnis aus:

Im Moment gibt es uns nichts. Aber lassen Sie uns herausfinden, was sich hinter dieser Adresse verbirgt! Der Code sieht folgendermaßen aus:
const libraryofbabel = require(`libraryofbabel`)({ lengthOfPage: 3200, alphabet: `abcdefghijklmnopqrstuvwxyz, .`,
Ergebnis:

Wir haben auf einer unendlichen Anzahl bedeutungsloser (ich wette) Seiten gefunden, wonach wir gesucht haben!
Dies ist jedoch bei weitem nicht der einzige Ort, an dem sich dieser Satz befindet. Beim nächsten Programmstart wird eine weitere Adresse generiert. Wenn Sie möchten, können Sie eine speichern und damit arbeiten. Hauptsache, der Inhalt der Seiten ändert sich nie. Schauen wir uns den Titel des Buches an, in dem sich unser Satz befindet. Der Code lautet wie folgt:
const libraryofbabel = require(`libraryofbabel`)({ lengthOfPage: 3200, alphabet: `abcdefghijklmnopqrstuvwxyz, .`,
Der Titel des Buches lautet ungefähr so:

Ehrlich gesagt sieht es nicht sehr attraktiv aus. Dann suchen wir ein Buch mit unserem Satz im Titel:
const libraryofbabel = require(`libraryofbabel`)({ lengthOfPage: 3200, alphabet: `abcdefghijklmnopqrstuvwxyz, .`,

Jetzt verstehen Sie, wie Sie diese Bibliothek verwenden. Lassen Sie mich die Möglichkeit demonstrieren, eine völlig andere Bibliothek zu erstellen. Jetzt wird es mit Einsen und Nullen gefüllt, jede Seite hat 100 Zeichen, die Adresse ist eine Hexadezimalzahl. Vergessen Sie nicht, die Bedingung für die Gleichheit der Längen des Alphabets und der Ziffernfolge unserer großen Zahl zu beachten. Wir werden zum Beispiel nach "10101100101010111001000000" suchen. Wir schauen:
const libraryofbabel = require(`libraryofbabel`)({ lengthOfPage: 100, alphabet: `1010101010101010`,

Lassen Sie uns einen Blick darauf werfen, wie Sie eine vollständige Übereinstimmung finden.
Kehren wir dazu zum alten Beispiel zurück und ersetzen
Sie im Code
libraryofbabel.search durch
libraryofbabel.searchExactly :
const libraryofbabel = require(`libraryofbabel`)({ lengthOfPage: 3200, alphabet: `abcdefghijklmnopqrstuvwxyz, .`,

Fazit
Nachdem Sie die Beschreibung des Bibliotheksoperationsalgorithmus gelesen haben, haben Sie wahrscheinlich bereits vermutet, dass dies eine Art Täuschung war.
Wenn Sie in der Bibliothek nach etwas Sinnvollem suchen, wird es einfach in einer anderen Form codiert und in einer anderen Form angezeigt. Aber es ist so schön serviert, dass Sie anfangen, an diese endlosen Reihen von Sechsecken zu glauben. In der Tat ist dies nichts weiter als eine mathematische Abstraktion. Aber die Tatsache, dass Sie in dieser Bibliothek absolut alles finden können, ist wahr. Die Wahrheit ist, dass Sie früher oder später absolut jeden Text erhalten können, wenn Sie zufällige Zeichenfolgen generieren. Zum besseren Verständnis dieses Themas können Sie den endlosen Affensatz studieren .Sie können sich auch andere Optionen für die Implementierung von Bibliotheken einfallen lassen: Verwenden Sie einen beliebigen Verschlüsselungsalgorithmus, wobei der Chiffretext die Adresse in Ihrer umfassenden Bibliothek ist. Entschlüsselung - Seiteninhalt abrufen. Oder vielleicht versuchenbase64 , m?Eine mögliche Verwendung der Bibliothek besteht darin, Kennwörter an einigen Stellen zu speichern. Erstellen Sie die Konfiguration, die Sie benötigen, und finden Sie heraus, wo sich Ihre Passwörter in der Bibliothek befinden (ja, sie sind bereits vorhanden. Und Sie dachten, Sie hätten sie erfunden?). Speichern Sie die Adresse. Und jetzt, wenn Sie ein Passwort suchen müssen, finden Sie es einfach in der Bibliothek. Dieser Ansatz ist jedoch gefährlich, da ein Angreifer die Bibliothekskonfiguration herausfinden und einfach Ihre Adresse verwenden kann. Wenn er jedoch nicht weiß, was er gefunden hat, ist es unwahrscheinlich, dass Ihre Daten ihn erreichen. Und ist es wirklich so eine gängige Methode zur Speicherung von Passwörtern? Nein, also hat es einen Platz zu sein.Diese Idee kann verwendet werden, um eine Vielzahl von "Bibliotheken" zu erstellen. Sie können nicht nur Zeichen, sondern auch ganze Wörter oder sogar Töne durchlaufen! Stellen Sie sich einen Ort vor, an dem Sie absolut jeden Ton hören können, der für die menschliche Wahrnehmung verfügbar ist, oder um eine Art Lied zu finden. In Zukunft werde ich auf jeden Fall versuchen, dies umzusetzen.Die Webversion in russischer Sprache ist hier verfügbar und wird auf meinem virtuellen Server bereitgestellt. Ich kenne nicht alle angenehmen Suchen nach dem Sinn des Lebens in der babylonischen Bibliothek oder was Sie schaffen wollen. Auf Wiedersehen! :) :)