Dieser Artikel vermittelt Ihnen relevantes Wissen über Javascript, das hauptsächlich die relevanten Inhalte der Datei-API, der Streams-API und der Web-Kryptographie-API in JavaScript vorstellt. Ich hoffe, dass es für alle hilfreich ist.
【Verwandte Empfehlung: Javascript-Video-Tutorial】
Wenn mehrere Kontexte auf SharedArrayBuffer zugreifen und gleichzeitig Vorgänge am Puffer ausgeführt werden, kann es zu Problemen mit Ressourcenkonflikten kommen. Die Atomics-API ermöglicht mehreren Kontexten das sichere Lesen und Schreiben eines SharedArrayBuffer, indem sie erzwingt, dass jeweils nur eine Operation auf dem Puffer ausgeführt werden kann.
Die Natur atomarer Operationen schließt Optimierungen (z. B. Neuordnung von Anweisungen) aus, die das Betriebssystem oder die Computerhardware normalerweise automatisch durchführen würden. Atomic-Operationen machen es auch unmöglich, gleichzeitig auf den Speicher zuzugreifen. Bei unsachgemäßer Verwendung kann es zu einer Verlangsamung der Programmausführung kommen. Aus diesem Grund besteht die ursprüngliche Entwurfsabsicht der Atomics-API darin, komplexe Multithread-JavaScript-Programme zu erstellen, die auf minimalen, aber stabilen Funktionen basieren Atomares Verhalten.
Atomics API bietet eine Reihe einfacher Methoden zur Durchführung direkter Änderungsoperationen. In der ECMA-Spezifikation sind diese Methoden als AtomicReadModifyWrite-Operationen definiert. Unter der Haube lesen diese Methoden einen Wert von einer Stelle im SharedArrayBuffer, führen arithmetische und bitweise Operationen aus und schreiben das Ergebnis schließlich an dieselbe Stelle. Die atomare Natur dieser Vorgänge bedeutet, dass die oben beschriebenen Lese-, Änderungs- und Rückschreibvorgänge der Reihe nach ausgeführt werden und nicht durch andere Threads unterbrochen werden.
//创建大小为1的缓冲区let sharedArrayBuffer = new SharedArrayBuffer(1); //基于缓冲创建Unit8Arraylet typedArray = new Unit8Array(sharedArrayBuffer); //所有ArrayBuffer全部初始化为0console.log(typedArray); //Unit8Array[0] //对索引0处的值执行原子加10Atomics.add(typedArray,0,10); //Unit8Array[10] //对索引0处的值执行原子减10Atomics.sub(typedArray,0,10); //Unit8Array[0]
Der JavaScript-Compiler des Browsers und die CPU-Architektur selbst haben die Befugnis, Anweisungen neu anzuordnen, um die Effizienz der Programmausführung zu verbessern. Unter normalen Umständen kann die Single-Thread-Umgebung von JavaScript diese Optimierung jederzeit durchführen, aber die Neuanordnung von Anweisungen in Multi-Threads kann zu Ressourcenkonflikten führen und ist äußerst schwierig zu beheben.
Die Atomics-API löst dieses Problem im Wesentlichen auf zwei Arten:
Die Reihenfolge aller atomaren Anweisungen wird niemals im Verhältnis zueinander neu angeordnet.
Durch die Verwendung von atomaren Lese- oder Schreibvorgängen wird sichergestellt, dass nicht alle Anweisungen relativ zu atomaren Lese- und Schreibvorgängen neu angeordnet werden.
Zusätzlich zum Lesen und Schreiben von Pufferwerten können Atomics.load() und Atomics.store() auch „Code-Zäune“ aufbauen. Die JavaScript-Engine stellt sicher, dass nicht-atomare Anweisungen lokal relativ zu Load() und Store() neu angeordnet werden können, diese Neuanordnung verletzt jedoch nicht die Grenzen atomarer Lese- und Schreibvorgänge.
const sharedArrayBuffer = new SharedArrayBuffer(4); const view = new Unit32Array(sharedArrayBuffer); //执行非原子写view[0] = 1; //非原子写可以保证在这个读操作之前完成,因此这里一定会读到1console.log(Atomics.load(view,0)); //1 //执行原子写Atomics.store(view,0,2); //非原子读可以保证在原子写完成后发生,这里一定会读到2console.log(view[0]); //2
Um ein kontinuierliches und unterbrechungsfreies Lesen und anschließendes Schreiben zu gewährleisten, bietet die Atomics API zwei Methoden: Exchange() und CompareExchange(). Atomics.exchange() führt einen einfachen Austausch durch, der garantiert, dass andere Threads den Austausch nicht unterbrechen.
const sharedArrayBuffer = new SharedArrayBuffer(4); const view = new Unit32Array(sharedArrayBuffer); //在索引0处写入10Atomics.store(view,0,10); //从索引0处读取值,然后在索引0处写入5console.log(Atomics.exchange(view,0,5)); //10 //从索引0处读取值console.log(Atomics.load(view,0)); //5
In einem Multithread-Programm möchte ein Thread möglicherweise nur dann in einen gemeinsam genutzten Puffer schreiben, wenn seit dem letzten Lesen kein anderer Thread den Wert geändert hat. Wenn der Wert nicht geändert wurde, kann dieser Thread den aktualisierten Wert sicher schreiben: Wenn der Wert geändert wurde, wird durch die Ausführung eines Schreibvorgangs der von anderen Threads berechnete Wert zerstört. Für diese Art von Aufgabe stellt die Atomics API die Methode „compare-Exchange()“ bereit. Diese Methode führt den Schreibvorgang nur aus, wenn der Wert am Zielindex mit dem erwarteten Wert übereinstimmt.
Ohne einen Sperrmechanismus können Multithread-Programme komplexe Anforderungen nicht unterstützen. Zu diesem Zweck stellt die Atomics API Methoden bereit, die Linux Futex (schneller User-Space-Mutex) nachahmen. Obwohl diese Methoden an sich sehr einfach sind, können sie als Grundkomponenten für komplexere Schließmechanismen dienen.
Alle atomaren Futex-Operationen können nur in Int32Array-Ansichten und nur innerhalb von Arbeitsthreads verwendet werden.
Cross-Document-Messaging, manchmal auch XDM (Cross-Document Messaging) genannt, ist die Möglichkeit, Informationen zwischen verschiedenen Ausführungskontexten (z. B. verschiedenen Arbeitsthreads oder Seiten aus verschiedenen Quellen) zu übertragen.
Die Kodierungs-API wird hauptsächlich zum Konvertieren zwischen Zeichenfolgen und stereotypen Arrays verwendet.
2. FileReader-Typ
readAsDataURL(file);//Lesen Sie die Datei und speichern Sie den Daten-URI des Inhalts im Ergebnisattribut.
readAsBinaryString(file);//Lesen Sie die Datei und speichern Sie die Binärdaten jedes Zeichens im Ergebnis attribute Medium
readAsArrayBuffer(file);//Lesen Sie die Datei und speichern Sie den Dateiinhalt im Ergebnisattribut in Form von ArrayBuffer
Eine synchrone Version des FileReader-Typs.
In einigen Fällen müssen Sie möglicherweise einen Teil der Datei anstelle der gesamten Datei lesen. Zu diesem Zweck stellt das File-Objekt eine Methode namens Slice() bereit. Die Methode „slice()“ empfängt zwei Parameter: das Startbyte und die Anzahl der Bytes im Yaodu-Bereich. Diese Methode gibt eine Instanz von Blob zurück, die eigentlich eine Oberklasse von File ist.
Blob stellt ein binäres großes Objekt dar, das der Kapselungstyp von JavaScript für nicht veränderbare Binärdaten ist. Arrays, die Zeichenfolgen, ArrayBuffers, ArrayBufferViews und sogar andere Blobs enthalten, können zum Erstellen von Blobs verwendet werden. Der Blob-Konstruktor kann einen Optionsparameter empfangen und darin den MIME-Typ angeben.
Die Streams API wurde entwickelt, um ein einfaches, aber grundlegendes Problem zu lösen: Wie verbraucht eine Webanwendung geordnete kleine Informationsblöcke anstelle großer Informationsblöcke? Es gibt zwei Hauptanwendungsszenarien für diese Funktion.
Streams API definiert drei Streams:
Lesbarer Stream: ein Stream, der Datenblöcke über eine bestimmte öffentliche Schnittstelle lesen kann. Daten gelangen intern von der zugrunde liegenden Quelle in den Stream und werden dann vom Verbraucher verarbeitet.
Beschreibbarer Stream: Ein Stream, der Datenblöcke über eine bestimmte öffentliche Schnittstelle schreiben kann. Der Produzent (Konsumer) schreibt Daten in den Stream und die Daten werden intern an den zugrunde liegenden Datenslot (Senke) übertragen.
Konvertierungsstream: Er besteht aus zwei Streams, der beschreibbare Stream wird zum Empfangen von Daten und der lesbare Stream zum Ausgeben von Daten verwendet. Bei diesen beiden Stream-Qualitätsprüfungen handelt es sich um Transformatoren, die Stream-Inhalte nach Bedarf prüfen und ändern können.
Web Cryptography API beschreibt eine Reihe von Kryptographie-Tools, die standardisieren, wie JavaScript die Verschlüsselung auf sichere und konventionelle Weise implementiert. Zu diesen Tools gehören das Generieren, Verwenden und Anwenden kryptografischer Schlüsselpaare, das Ver- und Entschlüsseln von Informationen sowie das zuverlässige Generieren von Zufallszahlen.
Viele Leute verwenden Math.random()
, wenn sie Zufallszahlen generieren müssen. Diese Methode ist im Browser als Pseudozufallszahlengenerator (PRNG, PseudoRandom Number Generator) implementiert. Das sogenannte Pseudo bezieht sich auf den Prozess der Generierung von Werten, der nicht wirklich zufällig ist. Die von PRNG generierten Werte simulieren lediglich zufällige Merkmale. Der PRNG des Browsers verwendet keine echte Zufallsquelle, sondern wendet nur einen festen Algorithmus auf einen internen Zustand an. Bei jedem Aufruf von Math.random()
wird dieser interne Zustand durch einen Algorithmus geändert und das Ergebnis in eine neue Zufallszahl umgewandelt. Beispielsweise verwendet die V8-Engine einen Algorithmus namens xorshift128+
, um diese Änderung durchzuführen. Math.random()
。这个方法在浏览器中是以伪随机数生成器(PRNG,PseudoRandom Number Generator)方式实现的。所谓的伪指的是生成值的过程不是真的随机。PRNG生成的值只是模拟了随机的特性。浏览器的PRNG并未使用真正的随机源,只是对一个内部状态应用了固定的算法。每次调用Math.random()
,这个内部状态都会被一个算法修改,而结果会被转换为一个新的随机数。例如,V8引擎使用了一个名为xorshift128+
的算法来执行这种修改。
由于算法本身是固定的,其输入只是之前的状态,因此随机数顺序也是确定的。xorshift128+
使用128位内部状态,而算法的设计让任何初始状态在重复自身之前都会产生2128-1个伪随机值。这种循环被称为置换循环,而这个循环的长度被称为一个周期。很明显,如果攻击者知道PRNG的内部状态,就可以预测后续生成的伪随机值。如果开发者无意中使用了PRNG生成了私有密钥用于加密,则攻击者就可以利用PRNG的这个特性算出私有密钥。
伪随机数生成器主要用于快速计算出看起来随机的数,不过并不适合用于加密算法,为解决这个问题,密码学安全伪随机数生成器(CSPRNG,Cryptographically Secure PseudoRandom Number Generator),额外增加了一个熵作为输入,例如测试硬件时间或其它无法预计行为的系统特性,虽然速度上不及PRNG,但是生成的值更难预测了,就可以用于加密。
Web Cryptography API引入了CSPRNG,这个CSPRNG可以通过crypto.getRandomValues()
在全局Crypto
对象上访问。与Math.random()
返回一个0到1之间的浮点数不同,getRandomValues()
xorshift128+
verwendet einen internen 128-Bit-Zustand und der Algorithmus ist so konzipiert, dass jeder Anfangszustand 2128-1 Pseudozufallswerte erzeugt, bevor er sich wiederholt. Diese Art von Schleife wird als Permutationsschleife bezeichnet, und die Länge dieser Schleife wird als Periode bezeichnet. Es ist offensichtlich, dass der Angreifer, wenn er den internen Zustand des PRNG kennt, die anschließend generierten Pseudozufallswerte vorhersagen kann. Wenn der Entwickler versehentlich PRNG verwendet, um einen privaten Schlüssel für die Verschlüsselung zu generieren, kann der Angreifer diese Funktion von PRNG verwenden, um den privaten Schlüssel zu berechnen. Pseudozufallszahlengenerator wird hauptsächlich zur schnellen Berechnung scheinbar zufälliger Zahlen verwendet, ist jedoch nicht für Verschlüsselungsalgorithmen geeignet. Zur Lösung dieses Problems ist ein kryptographisch sicherer Pseudozufallszahlengenerator (CSPRNG, Cryptographically Secure PseudoRandom Number Generator) erforderlich Als Eingabe hinzugefügt, beispielsweise zum Testen der Hardwarezeit oder anderer Systemeigenschaften mit unvorhersehbarem Verhalten. Obwohl es nicht so schnell ist wie PRNG, ist der generierte Wert schwieriger vorherzusagen und kann zur Verschlüsselung verwendet werden. Web Cryptography API führt CSPRNG ein, auf das über crypto.getRandomValues()
auf das globale Crypto
-Objekt zugegriffen werden kann. Im Gegensatz zu Math.random()
, das eine Gleitkommazahl zwischen 0 und 1 zurückgibt, schreibt getRandomValues()
Zufallswerte in das stereotype Array, das ihm als Parameter übergeben wird. Die Klasse des stereotypen Arrays spielt keine Rolle, da der zugrunde liegende Puffer mit Zufallsbits gefüllt wird.
【Verwandte Empfehlungen: Javascript-Video-Tutorial, Web-Frontend】
Das obige ist der detaillierte Inhalt vonLernen Sie die Datei-API, die Streams-API und die Web-Kryptografie-API in JavaScript kennen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!