- Trong lúc lướt web, tác giả phát hiện một thành phần ASCII art thú vị. Trông rất ấn tượng nhưng khó hiểu được cách triển khai
- Khi kiểm tra mã nguồn thì thấy mã đã được rút gọn (minified)
Ví dụ về mã đã rút gọn
- Một phần mã như sau:
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 };
Yêu cầu ChatGPT giải thích mã
- Tác giả đã yêu cầu ChatGPT "hãy giải thích đoạn mã này"
- Phản hồi của ChatGPT:
Đoạn mã được cung cấp khá phức tạp, nhưng tôi sẽ giải thích từng phần và chức năng của nó theo cách dễ hiểu.
Tổng quan
- Định nghĩa nhiều hàm và thành phần bằng JavaScript
- Tạo nội dung văn bản động trong một ứng dụng React
- Tạo hiệu ứng trực quan bằng ASCII art hoặc bộ ký tự được định nghĩa sẵn
Các thành phần và hàm chính
- Chọn bộ ký tự:
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;
- Lấy các hàm từ
Mathvà định nghĩa hai bộ ký tự - Chọn bộ ký tự theo thời gian hiện tại
- Lưu độ dài của bộ ký tự đã chọn
- Hàm chọn ký tự động:
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];
}
- Hàm
eTtạo ký tự dựa trên vị trí đầu vào và thời gian hiện tại - Điều chỉnh vị trí rồi chọn một ký tự từ bộ ký tự
- Component React hiển thị nội dung động (
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" } }) });
};
- Component React này định kỳ cập nhật nội dung của phần tử
divbằng các ký tự được tạo động - Tính số cột và số hàng theo kích thước cửa sổ rồi lấp đầy
divbằng ký tự
Mã đã được chuyển sang TypeScript
- Tác giả yêu cầu ChatGPT chuyển mã sang TypeScript
- Phản hồi của 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 ; };
Tóm tắt của GN⁺
- Bài viết này giải thích cách hiểu và khôi phục mã đã được rút gọn
- Cho thấy quá trình dùng ChatGPT để giải thích mã phức tạp và chuyển nó sang TypeScript
- Đề xuất cách tận dụng các công cụ AI để hỗ trợ việc khôi phục và hiểu mã nguồn
- Các dự án có chức năng tương tự gồm
PrettiervàUglifyJS
1 bình luận
Ý kiến trên Hacker News
Tác giả của HumanifyJS đã phát triển một công cụ dựa trên LLM. Công cụ này sử dụng LLM ở cấp độ AST để đảm bảo mã vẫn hoạt động sau khi được unminification
Việc JS minification mang tính cơ học và tương đối đơn giản. Dù khá phiền nếu làm thủ công, bản thân phép biến đổi này bị giới hạn nên vẫn có thể đọc được bằng cách ghi chú lại một số định danh để theo dõi
Unminification hay unobfuscation nói chung vẫn là một bài toán chưa được giải quyết. Trước đây có người từng viết các chương trình bị làm rối có chủ đích, nhưng ChatGPT thậm chí không hiểu được cả ở mức bề mặt
Một số nhà phát triển có thể không hài lòng vì họ dùng minification để làm rối mã. Công cụ "mã hóa" mã do các phiên bản cũ của ColdFusion cung cấp từng sử dụng một thuật toán yếu, nhưng vẫn có người tin rằng nó an toàn và dùng nó
Trong tiêu đề, có lẽ dùng ChatGPT hoặc gpt-4 thay vì OpenAI sẽ phù hợp hơn
Đây là một ví dụ về năng lực trí tuệ vượt trội hơn con người. LLM hiểu được unminification, và trong chủ đề cụ thể này, chúng vượt trội hơn con người
LLM rất giỏi trong việc biến đổi văn bản. Đây là thế mạnh cốt lõi của chúng
Khoảng 1 năm trước, có người đã thử dùng GPT để gỡ rối mã độc nhưng thấy tự phân tích mã vẫn tốt hơn. Khi thử lại gần đây, GPT đã có thể hiểu được ở mức độ nào đó
Dùng LLM để làm cho mã phức tạp dễ đọc hơn mang lại cảm giác rất giải phóng. Đôi khi chúng bỏ sót chi tiết, nhưng điều đó có thể tự kiểm tra lại
Nếu mã đã unminified không khớp với mã minified thì tính hữu dụng sẽ giảm đi rất nhiều. Trong nhiều trường hợp, sau khi chạy mã cũng không thể kiểm tra được sự khác biệt
Khi muốn biết thuật toán tính toán của một website, chỉ cần đưa JS đã minified vào ChatGPT là có thể nắm được khá dễ dàng. Có thể hình dung một tương lai nơi LLM có thể clone toàn bộ một ứng dụng SAAS