- Ao navegar pela internet, foi encontrado um componente interessante de arte ASCII. Parecia muito legal, mas era difícil entender como tinha sido implementado
- Ao verificar o código-fonte, o código estava minificado
Exemplo de código minificado
- Parte do código era a seguinte:
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 };
Pedido ao ChatGPT para explicar o código
- Foi pedido ao ChatGPT: "explique o código"
- Resposta do ChatGPT:
O código fornecido é bastante complexo, mas vou explicar cada parte e sua função de forma clara.
Visão geral
- Define várias funções e componentes usando JavaScript
- Gera conteúdo de texto dinâmico em uma aplicação React
- Cria um efeito visual usando arte ASCII ou um conjunto de caracteres predefinido
Principais componentes e funções
- Seleção do conjunto de caracteres:
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;
- Importa funções de
Mathe define dois conjuntos de caracteres - Seleciona um conjunto de caracteres com base no horário atual
- Armazena o comprimento do conjunto de caracteres selecionado
- Função de seleção dinâmica de caracteres:
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];
}
- A função
eTgera caracteres com base na posição de entrada e no tempo atual - Ajusta a posição e seleciona um caractere do conjunto de caracteres
- Componente React (
tT) que exibe conteúdo dinâmico:
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" } }) });
};
- Este componente React atualiza periodicamente o conteúdo de um elemento
divcom caracteres gerados dinamicamente - Calcula o número de colunas e linhas de acordo com o tamanho da janela e preenche a
divcom caracteres
Código convertido para TypeScript
- Foi pedido ao ChatGPT o código convertido para TypeScript
- Resposta do 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 ; };
Resumo do GN⁺
- Este texto explica como entender e restaurar código minificado
- Mostra o processo de usar o ChatGPT para explicar código complexo e convertê-lo para TypeScript
- Apresenta uma forma de usar ferramentas de IA para ajudar na restauração e compreensão de código
- Projetos com funcionalidade semelhante incluem
PrettiereUglifyJS
1 comentários
Comentários do Hacker News
O autor do HumanifyJS desenvolveu uma ferramenta baseada em LLM. Ela usa LLM no nível de AST para garantir que o código continue funcionando após o unminification
A minificação de JS é mecânica e relativamente simples. É incômodo fazer isso manualmente, mas a transformação em si é limitada, então dá para ler acompanhando os identificadores com algumas anotações
Unminification ou unobfuscation em geral ainda é um problema não resolvido. No passado, alguém escreveu intencionalmente programas ofuscados, e o ChatGPT não conseguia entendê-los nem em nível superficial
Alguns desenvolvedores podem ficar insatisfeitos porque usam minificação para ofuscação. Havia pessoas que usavam a ferramenta de "criptografia" de código oferecida em versões antigas do ColdFusion achando que era segura, apesar de o algoritmo ser fraco
Pode ser mais apropriado usar ChatGPT ou gpt-4 no título em vez de OpenAI
Este trabalho é um exemplo de desempenho intelectual superior ao humano. O LLM entende unminification e, neste tópico específico, é superior aos humanos
LLMs são excelentes em transformação de texto. Esse é o ponto forte central deles
Cerca de um ano atrás, alguém tentou usar GPT para desfazer a ofuscação de malware, mas analisar o código diretamente era melhor. Ao tentar de novo recentemente, já foi possível entendê-lo em certa medida
Usar LLM para tornar códigos complexos mais legíveis é algo muito libertador. Às vezes ele deixa passar detalhes, mas isso pode ser verificado diretamente
Se o código unminified não corresponder ao código minified, a utilidade cai bastante. Em muitos casos, não dá para verificar as diferenças depois de executar o código
Quando alguém quer saber o algoritmo de cálculo de um site, podia colocar o JS minificado no ChatGPT e entender facilmente. Dá para imaginar um futuro em que LLMs consigam clonar um app SaaS inteiro