- Beim Surfen im Internet wurde eine interessante ASCII-Art-Komponente entdeckt. Sie sah großartig aus, aber es war schwer zu verstehen, wie sie implementiert war.
- Nachsehen im Quellcode zeigte, dass der Code minimiert war.
Beispiel für minimierten Code
- Ein Teil des Codes sah wie folgt aus:
const { floor: ra, abs: KE, min: QE } = Math, O5 = ["reactive.network REACTIVE.NETWORK", "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"], G7 = Date.now() % 3 ? O5[1] : O5[0], V5 = G7.length, JE = { fps: 60 };
ChatGPT um Erklärung des Codes gebeten
- ChatGPT wurde gebeten, „den Code zu erklären“.
- Antwort von ChatGPT:
Der bereitgestellte Code ist ziemlich komplex, aber ich werde die einzelnen Teile und ihre Funktion leicht verständlich erklären.
Überblick
- Mit JavaScript werden mehrere Funktionen und Komponenten definiert.
- In einer React-Anwendung werden dynamische Textinhalte erzeugt.
- Es wird ein visueller Effekt mit ASCII-Art oder einem vordefinierten Zeichensatz erzeugt.
Wichtige Komponenten und Funktionen
- Auswahl des Zeichensatzes:
const { floor: ra, abs: KE, min: QE } = Math;
const O5 = ["reactive.network REACTIVE.NETWORK", "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"];
const G7 = Date.now() % 3 ? O5[1] : O5[0];
const V5 = G7.length;
- Funktionen aus
Mathwerden übernommen und zwei Zeichensätze definiert. - Je nach aktueller Zeit wird ein Zeichensatz ausgewählt.
- Die Länge des ausgewählten Zeichensatzes wird gespeichert.
- Funktion zur dynamischen Zeichenauswahl:
function eT(e, t, n, r) {
const i = t.time * 8e-5;
const s = QE(t.cols, t.rows);
const o = t.metrics.aspect * 0.2;
const l = { x: ((4 * (e.x - t.cols / 6.25)) / s) * o, y: (5 * (e.y - t.rows / 4)) / s };
const u = ra(KE(YE(l) - i) * V5 + (ra(e.x / 1) % 2) * 2) % V5;
return G7[u];
}
- Die Funktion
eTerzeugt anhand der Eingabeposition und der aktuellen Zeit ein Zeichen. - Sie passt die Position an und wählt ein Zeichen aus dem Zeichensatz aus.
- React-Komponente zur Anzeige dynamischer Inhalte (
tT):
const tT = () => {
const e = j.useRef(null);
const [t, n] = j.useState({ height: null, width: null });
j.useEffect(() => {
function r() {
n({ height: window.innerHeight, width: window.innerWidth });
}
if (typeof window < "u") {
n({ height: window.innerHeight, width: window.innerWidth });
window.addEventListener("resize", r);
return () => window.removeEventListener("resize", r);
}
}, []);
j.useEffect(() => {
const r = e.current;
if (!r) return;
const i = 12;
const s = ra(t.width / i) * 1.6;
const o = ra(t.height / i);
const l = { aspect: s / o };
const u = setInterval(() => {
let c = "";
for (let d = 0; d < o; d++) {
for (let f = 0; f < s; f++) c += eT({ x: f, y: d }, { cols: s, rows: o, metrics: l, time: Date.now() });
c += ` `;
}
r.textContent = c;
}, 1e3 / JE.fps);
return () => clearInterval(u);
}, [t]);
return a.jsx("div", { style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }, children: a.jsx("div", { ref: e, style: { width: "100%", height: "100%", whiteSpace: "pre", overflow: "hidden" } }) });
};
- Diese React-Komponente aktualisiert den Inhalt eines
div-Elements periodisch mit dynamisch erzeugten Zeichen. - Sie berechnet anhand der Fenstergröße die Anzahl von Spalten und Zeilen und füllt das
divmit Zeichen.
In TypeScript umgewandelter Code
- ChatGPT wurde gebeten, den in TypeScript umgewandelten Code zu liefern.
- Antwort von ChatGPT:
import React, { useEffect, useRef, useState } from 'react'; const selectedCharacterSet = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"; const characterSetLength = selectedCharacterSet.length; const calculateCharacter = ( x: number, y: number, cols: number, rows: number, aspect: number, time: number, ): string => { const timeFactor = time * 0.000_08; const size = Math.min(cols, rows); const aspectRatio = aspect * 0.2; const position = { x: ((4 * (x - cols / 6.25)) / size) * aspectRatio, y: (5 * (y - rows / 4)) / size, }; const index = Math.floor( Math.abs( Math.cos(position.x * position.x - position.y * position.y) - timeFactor, ) * characterSetLength + (Math.floor(x) % 2) * 2, ) % characterSetLength; return selectedCharacterSet[index]; }; type Size = { height: null | number; width: null | number; }; const AsciiArtGenerator: React.FC = () => { const textRef = useRef(null); const [size, setSize] = useState({ height: null, width: null }); useEffect(() => { const handleResize = () => { setSize({ height: window.innerHeight, width: window.innerWidth }); }; handleResize(); window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, []); useEffect(() => { const element = textRef.current; if (!element || !size.width || !size.height) return undefined; const cols = Math.floor(size.width / 12) * 1.6; const rows = Math.floor(size.height / 12); const aspectRatio = cols / rows; const intervalId = setInterval(() => { let content = ''; for (let y = 0; y < rows; y++) { for (let x = 0; x < cols; x++) { content += calculateCharacter(x, y, cols, rows, aspectRatio, Date.now()); } content += '\n'; } element.textContent = content; }, 1_000 / 60); return () => { clearInterval(intervalId); }; }, [size]); return ( ); }; export default () => { return ; };
Zusammenfassung von GN⁺
- Dieser Beitrag erklärt, wie man minimierten Code versteht und wiederherstellt.
- Er zeigt den Prozess, mit ChatGPT komplexen Code erklären zu lassen und ihn in TypeScript umzuwandeln.
- Er stellt vor, wie sich AI-Tools einsetzen lassen, um die Wiederherstellung und das Verständnis von Code zu unterstützen.
- Projekte mit ähnlicher Funktionalität sind
PrettierundUglifyJS.
1 Kommentare
Hacker-News-Kommentar
Der Autor von HumanifyJS hat ein LLM-basiertes Tool entwickelt. Dieses Tool nutzt LLMs auf AST-Ebene, um sicherzustellen, dass der Code auch nach dem Unminifying funktionsfähig bleibt
JS-Minifizierung ist mechanisch und vergleichsweise einfach. Von Hand ist sie mühsam, aber die Umwandlung selbst ist begrenzt, sodass man den Code mit ein paar Notizen zur Verfolgung von Bezeichnern lesen kann
Allgemeines Unminifying oder Deobfuskieren ist weiterhin ein ungelöstes Problem. Früher habe ich absichtlich obfuskierte Programme geschrieben, und ChatGPT konnte sie nicht einmal oberflächlich verstehen
Einige Entwickler könnten unzufrieden sein, weil sie Minifizierung zur Obfuskierung verwenden. Das Code-"Verschlüsselungs"-Tool in älteren ColdFusion-Versionen nutzte einen schwachen Algorithmus, dennoch hielten manche es für sicher und verwendeten es
Im Titel wäre es möglicherweise passender, statt OpenAI ChatGPT oder gpt-4 zu verwenden
Diese Arbeit ist ein Beispiel für eine intellektuelle Leistung, die Menschen übertrifft. LLMs verstehen Unminifying, und bei diesem speziellen Thema sind sie Menschen überlegen
LLMs sind hervorragend bei Texttransformation. Das ist ihre zentrale Stärke
Vor etwa einem Jahr habe ich versucht, mit GPT Malware zu deobfuskieren, aber direkte Codeanalyse war besser. Als ich es vor Kurzem erneut probierte, konnte es einiges verstehen
Es ist sehr befreiend, mit LLMs komplexen Code lesbarer zu machen. Manchmal übersehen sie Details, aber das kann man selbst überprüfen
Wenn der unminifizierte Code nicht mit dem minifizierten Code übereinstimmt, sinkt der Nutzen erheblich. In vielen Fällen kann man die Unterschiede nach der Ausführung des Codes nicht erkennen
Wenn ich den Berechnungsalgorithmus einer Website wissen wollte, konnte ich minifiziertes JS in ChatGPT einfügen und es leicht nachvollziehen. Man kann sich eine Zukunft vorstellen, in der LLMs komplette SaaS-Apps klonen können