- En naviguant sur Internet, l’auteur est tombé sur un composant en ASCII art intéressant. Le rendu était impressionnant, mais difficile de comprendre comment il était implémenté
- En consultant le code source, il a constaté que le code était minifié
Exemple de code minifié
- Une partie du code ressemblait à ceci :
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 };
Demande d’explication du code à ChatGPT
- L’auteur a demandé à ChatGPT de « décrire le code »
- Réponse de ChatGPT :
Le code fourni est assez complexe, mais je vais expliquer clairement chaque partie et sa fonction.
Vue d’ensemble
- Il définit plusieurs fonctions et composants en JavaScript
- Il génère du contenu texte dynamique dans une application React
- Il produit un effet visuel à l’aide d’ASCII art ou d’un jeu de caractères prédéfini
Principaux composants et fonctions
- Sélection du jeu de caractères :
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;
- Il récupère des fonctions de
Mathet définit deux jeux de caractères - Il choisit un jeu de caractères selon l’heure courante
- Il stocke la longueur du jeu de caractères sélectionné
- Fonction de sélection dynamique des caractères :
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];
}
- La fonction
eTgénère un caractère en fonction de la position d’entrée et du temps courant - Elle ajuste la position puis choisit un caractère dans le jeu sélectionné
- Composant React qui affiche le contenu dynamique (
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" } }) });
};
- Ce composant React met périodiquement à jour le contenu d’un élément
divavec des caractères générés dynamiquement - Il calcule le nombre de colonnes et de lignes selon la taille de la fenêtre puis remplit le
divavec des caractères
Code converti en TypeScript
- L’auteur a demandé à ChatGPT de convertir le code en TypeScript
- Réponse de 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 ; };
Résumé de GN⁺
- Cet article explique comment comprendre et restaurer du code minifié
- Il montre comment utiliser ChatGPT pour expliquer du code complexe et le convertir en TypeScript
- Il présente une manière d’exploiter des outils d’IA pour aider à la restauration et à la compréhension du code
- Des projets aux fonctionnalités similaires incluent
PrettieretUglifyJS
1 commentaires
Avis Hacker News
L’auteur de HumanifyJS a développé un outil basé sur les LLM. Cet outil utilise un LLM au niveau de l’AST pour garantir que le code continue de fonctionner après la déminification
La minification JS est mécanique et relativement simple. C’est fastidieux à faire manuellement, mais la transformation elle-même est limitée, donc on peut la lire en suivant les identifiants avec quelques notes
La déminification ou la désobfuscation générale reste un problème non résolu. J’ai déjà écrit par le passé des programmes volontairement obfusqués, et ChatGPT ne les comprenait pas, même à un niveau superficiel
Certains développeurs pourraient être mécontents, car ils utilisent la minification à des fins d’obfuscation. Dans d’anciennes versions de ColdFusion, l’outil de « chiffrement » de code reposait sur un algorithme faible, mais certaines personnes l’utilisaient quand même en pensant qu’il était sûr
Il serait peut-être plus approprié d’utiliser ChatGPT ou gpt-4 dans le titre plutôt qu’OpenAI
Ce travail est un exemple de performance intellectuelle supérieure à celle de l’humain. Les LLM comprennent la déminification et, sur ce sujet précis, ils sont meilleurs que les humains
Les LLM excellent dans la transformation de texte. C’est leur principale force
Il y a environ un an, j’ai essayé d’utiliser GPT pour désobfusquer un malware, mais analyser directement le code donnait de meilleurs résultats. En réessayant récemment, il a pu le comprendre dans une certaine mesure
Utiliser un LLM pour rendre du code complexe plus lisible est très libérateur. Il manque parfois des détails, mais on peut les vérifier soi-même
Si le code déminifié ne correspond pas au code minifié, son utilité diminue fortement. Dans de nombreux cas, il est impossible de vérifier les différences après l’exécution du code
Quand on veut connaître l’algorithme de calcul d’un site web, il suffit souvent de coller le JS minifié dans ChatGPT pour le comprendre facilement. On peut imaginer un futur où les LLM pourront cloner une application SaaS entière