- ระหว่างท่องเว็บ ผู้เขียนพบคอมโพเนนต์ ASCII art ที่น่าสนใจ มันดูเท่มากแต่ยากจะเข้าใจว่าถูกสร้างขึ้นอย่างไร
- เมื่อตรวจดูซอร์สโค้ดก็พบว่าโค้ดถูกย่อขนาด (Minified) ไว้
ตัวอย่างโค้ดที่ถูกย่อขนาด
- บางส่วนของโค้ดมีลักษณะดังนี้:
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 อธิบายโค้ด
- ผู้เขียนขอให้ ChatGPT “อธิบายโค้ดนี้”
- คำตอบของ ChatGPT:
โค้ดที่ให้มาค่อนข้างซับซ้อน แต่ผมจะอธิบายแต่ละส่วนและหน้าที่ของมันให้อยู่ในรูปแบบที่เข้าใจง่าย
ภาพรวม
- ใช้ JavaScript เพื่อกำหนดฟังก์ชันและคอมโพเนนต์หลายตัว
- สร้างเนื้อหาข้อความแบบไดนามิกในแอปพลิเคชัน React
- สร้างเอฟเฟกต์ภาพโดยใช้ ASCII art หรือชุดอักขระที่กำหนดไว้ล่วงหน้า
คอมโพเนนต์และฟังก์ชันหลัก
- การเลือกชุดอักขระ:
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;
- ดึงฟังก์ชันจาก
Mathและกำหนดชุดอักขระสองชุด - เลือกชุดอักขระตามเวลาปัจจุบัน
- เก็บความยาวของชุดอักขระที่เลือกไว้
- ฟังก์ชันเลือกอักขระแบบไดนามิก:
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];
}
- ฟังก์ชัน
eTสร้างอักขระตามตำแหน่งอินพุตและเวลาปัจจุบัน - ปรับตำแหน่งและเลือกอักขระจากชุดอักขระ
- React คอมโพเนนต์ที่แสดงเนื้อหาแบบไดนามิก (
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" } }) });
};
- React คอมโพเนนต์นี้จะอัปเดตคอนเทนต์ของ
divเป็นอักขระที่สร้างแบบไดนามิกเป็นระยะ - คำนวณจำนวนคอลัมน์และแถวตามขนาดหน้าต่าง แล้วเติม
divด้วยอักขระ
โค้ดที่แปลงเป็น TypeScript
- ผู้เขียนขอให้ ChatGPT แปลงโค้ดเป็น TypeScript
- คำตอบของ 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 ; };
สรุปโดย GN⁺
- บทความนี้อธิบายวิธีทำความเข้าใจและกู้คืนโค้ดที่ถูกย่อขนาด
- แสดงกระบวนการใช้ ChatGPT เพื่ออธิบายโค้ดที่ซับซ้อนและแปลงเป็น TypeScript
- นำเสนอวิธีใช้เครื่องมือ AI เพื่อช่วยในการกู้คืนและทำความเข้าใจโค้ด
- โปรเจ็กต์ที่มีฟังก์ชันคล้ายกันได้แก่
PrettierและUglifyJS
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ผู้สร้าง HumanifyJS ได้พัฒนาเครื่องมือที่ใช้ LLM เครื่องมือนี้ใช้ LLM ในระดับ AST เพื่อรับประกันว่าโค้ดยังคงทำงานได้หลังจาก unminification
การทำ JS minification เป็นกระบวนการเชิงกลไกและค่อนข้างเรียบง่าย แม้จะยุ่งยากหากทำด้วยมือ แต่การแปลงนั้นมีขอบเขตจำกัด จึงยังพออ่านได้ด้วยการจดบันทึกเพื่อติดตาม identifier บางตัว
unminification หรือ unobfuscation แบบทั่วไปยังคงเป็นปัญหาที่ยังแก้ไม่ตก ในอดีตมีการเขียนโปรแกรมที่ทำให้อ่านยากโดยตั้งใจ และ ChatGPT ก็ไม่สามารถเข้าใจได้แม้ในระดับผิวเผิน
นักพัฒนาบางคนอาจไม่พอใจ เพราะพวกเขาใช้ minification เพื่อทำ obfuscation โดยเครื่องมือ "เข้ารหัส" โค้ดที่มีใน ColdFusion เวอร์ชันเก่า แม้จะใช้อัลกอริทึมที่อ่อนแอ ก็ยังมีคนที่คิดว่ามันปลอดภัยและใช้งานมัน
ในชื่อเรื่อง การใช้ ChatGPT หรือ gpt-4 แทน OpenAI อาจเหมาะสมกว่า
งานนี้เป็นตัวอย่างของความสามารถทางปัญญาที่เหนือกว่ามนุษย์ LLM เข้าใจ unminification และในหัวข้อเฉพาะนี้ทำได้ดีกว่ามนุษย์
LLM เก่งมากในการแปลงข้อความ นี่คือจุดแข็งหลักของพวกมัน
เมื่อประมาณ 1 ปีก่อน เคยลองใช้ GPT เพื่อจัดการ obfuscation ของมัลแวร์ แต่การวิเคราะห์โค้ดด้วยตัวเองดีกว่า พอลองใหม่เมื่อไม่นานมานี้ มันก็พอเข้าใจได้ในระดับหนึ่ง
การใช้ LLM เพื่อทำให้โค้ดซับซ้อนอ่านง่ายขึ้นนั้นให้ความรู้สึกปลดปล่อยมาก บางครั้งมันพลาดรายละเอียดไปบ้าง แต่สามารถตรวจสอบเองได้
หากโค้ดที่ผ่านการ unminify แล้วไม่สอดคล้องกับโค้ดที่ถูก minify ประโยชน์ใช้งานจะลดลงอย่างมาก ในหลายกรณีหลังจากรันโค้ดแล้วก็ไม่สามารถตรวจสอบความแตกต่างได้
เมื่ออยากรู้ว่าอัลกอริทึมการคำนวณของเว็บไซต์ทำงานอย่างไร ก็สามารถใส่ JS ที่ถูก minify ลงใน ChatGPT แล้วทำความเข้าใจได้อย่างง่ายดาย สามารถจินตนาการถึงอนาคตที่ LLM โคลนแอป SAAS ทั้งระบบได้