2 คะแนน โดย GN⁺ 5 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เสื้อยืดลาย Akamai ที่วางขายในร้าน Uniqlo มีการพิมพ์ โค้ด bash ที่ถูกทำให้อ่านยาก ซึ่งนำผลลัพธ์จาก base64 --decode ไปรันด้วย eval แต่จริง ๆ แล้วเป็นอีสเตอร์เอ็กสำหรับแคมเปญ Peace for All
  • เมื่อถอด Here string ที่เข้ารหัสด้วย Base64 จะได้สคริปต์ที่แสดงข้อความ ♥PEACE♥FOR♥ALL♥ ซ้ำ ๆ ในเทอร์มินัลเป็น แอนิเมชันคลื่นไซน์
  • Base64 ไม่มีการแก้ไขข้อผิดพลาด ทำให้การถอดข้อความจากภาพเป็นเรื่องยุ่งยาก ผู้เขียนจึงตรวจสอบ padding ของสตริง รวมถึงเครื่องหมายคำพูดและวงเล็บปีกกาให้ตรงกัน แล้วเปรียบเทียบผลจาก Android OCR, Tesseract และ Claude ก่อนจัดระเบียบ
  • สคริปต์ที่ถอดรหัสแล้วใช้ tput, bc และ ANSI escape แบบ 256 สีร่วมกัน เพื่อคำนวณตำแหน่งตัวอักษรและสีตามขนาดเทอร์มินัล และคืนค่าเคอร์เซอร์เมื่อจบด้วย CTRL+C
  • Akamai อธิบายว่าโค้ดจริงด้านหลังเสื้อเชื่อมโยงกับ Linux และมีการแก้ไขฟอนต์จากที่คาดไว้ตอนแรกว่าเป็น Consolas เป็น Roboto Mono

โค้ดที่รันได้บนด้านหลังเสื้อยืด

  • ด้านหน้าเสื้อยืด Uniqlo x Akamai Peace for All มีรูปหัวใจอยู่ในวงเล็บปีกกา ส่วนด้านหลังพิมพ์ บล็อกตัวอักษรและตัวเลข ขนาดใหญ่
  • เมื่อดูใกล้ ๆ บล็อกดังกล่าวเป็นโค้ด bash ที่เริ่มด้วย shebang และมีโครงสร้างคือถอด Here string ที่เข้ารหัสด้วย Base64 ด้วย base64 --decode แล้วส่งต่อให้ eval
  • มองเผิน ๆ อาจดูเหมือน “วิธีแพร่กระจายไวรัส” แต่จุดประสงค์จริงคือการแสดง ข้อความอีสเตอร์เอ็ก
  • เสื้อยืดนี้เป็นผลิตภัณฑ์ที่ Akamai ออกแบบเพื่อสนับสนุน แคมเปญ Peace for All ของ Uniqlo

กระบวนการ OCR และการถอดข้อความ

  • Base64 ไม่มีฟังก์ชันแก้ไขข้อผิดพลาด ดังนั้นหากต้องการย้ายสตริงที่พิมพ์อยู่ให้เป็นรูปแบบที่รันได้ จำเป็นต้อง ถอดข้อความให้สมบูรณ์แบบ
  • สตริงจบด้วย padding ตามที่คาดไว้ และเครื่องหมายคำพูดกับวงเล็บปีกกาก็ตรงกัน จึงมีความเป็นไปได้สูงว่าเป็นโค้ดที่ครบถ้วน
  • การถอดข้อความใช้สามวิธีร่วมกัน
    • OCR ในตัวของ circle-to-search บน Android
    • Tesseract พร้อมตัวเลือกและการปรับแต่งบางอย่าง
    • OCR และการสร้างตารางตำแหน่งผ่าน Claude
  • นำผลทั้งสามมาเปรียบเทียบด้วย diff เพื่อหาจุดที่ไม่ตรงกัน แล้วจัดการส่วนที่เหลือด้วยมือ
  • ดีไซน์เสื้อยืดแบบอื่นในไลน์ Uniqlo x Akamai เดียวกันดูเหมือนถูกตัดออกจากบล็อกโค้ดที่กว้างกว่า โดย imports ถูกตัด และ return จบแค่ retu ทำให้อยู่ในสภาพที่คอมไพล์ไม่ได้

พฤติกรรมของสคริปต์ bash ที่ถอดรหัสแล้ว

  • เมื่อถอดรหัส Base64 จะพบ อีสเตอร์เอ็ก bash ที่มีคอมเมนต์ประกอบอย่างดี
  • ตอนต้นของสคริปต์มีข้อความแสดงความยินดีเป็นภาษาอังกฤษและญี่ปุ่น
    • Congratulations! You found the easter egg! ❤️
    • おめでとうございます!隠されたサプライズを見つけました!❤️
  • สตริงเป้าหมายของแอนิเมชันจะวนซ้ำในรูปแบบ ♥PEACE♥FOR♥ALL♥PEACE♥FOR♥ALL...
  • ขนาดเทอร์มินัลถูกดึงด้วย tput cols, tput lines และคำนวณความยาวสตริงด้วย ${#text} ของ bash
  • เคอร์เซอร์ถูกซ่อนด้วย tput civis และเมื่อได้รับ SIGINT จะคืนเคอร์เซอร์ด้วย tput cnorm; exit

วิธีสร้างแอนิเมชัน

  • ลูปทำงานต่อเนื่องในรูปแบบ ลูปไม่สิ้นสุด for (( t=0; ; t+=1 ))
  • ในแต่ละรอบ จะดึงตัวอักษรที่จะพิมพ์ปัจจุบันจาก text ทีละตัว
  • การคำนวณตำแหน่งใช้ bc -l เพื่อหาค่าไซน์
    • angle = t * 0.2
    • sine_value = s(angle)
    • x = (cols / 2) + (cols / 4) * sine_value
  • ค่า x ที่คำนวณได้จะถูกปรับให้อยู่ในขอบเขตเทอร์มินัล ไม่ต่ำกว่า 0 และไม่เกิน cols - 1
  • สีถูกคำนวณเป็น กราเดียนต์ ระหว่างค่า 12 ซึ่งเป็น cyan และค่า 208 ซึ่งเป็น orange ในพาเล็ต 256 สี
  • การแสดงผลใช้ ANSI escape และ tput cup เพื่อพิมพ์ตัวอักษรที่ลงสีแล้วในตำแหน่งที่กำหนด จากนั้นเลื่อนลงบรรทัดถัดไปด้วยการขึ้นบรรทัดใหม่
  • ผลลัพธ์คือข้อความแคมเปญ Peace for All ปรากฏในเทอร์มินัลเป็น ลูปคลื่นไซน์ ต่อเนื่อง

ฟอนต์และคำอธิบายดีไซน์จาก Akamai

  • ตอนแรกมีการคาดว่าฟอนต์คือ Consolas แต่หลังจากผู้ใช้ Hacker News ชื่อ ralphinus ตรวจสอบ จึงแก้ไขเป็น Roboto Mono
  • หลักฐานที่ทำให้คาดผิด ได้แก่เลข 0 ที่มีเส้นเฉียงตื้น ๆ, เลข 1 ที่ไม่มี serif และเส้นโค้งมนของ BDyg กับเลข 2
  • ตอนเปิดตัวเสื้อยืด Akamai อธิบายข้อความของดีไซน์ผ่าน ข่าวประชาสัมพันธ์
  • สีน้ำตาลอมเหลืองสดสื่อถึงเคสพลาสติก “beige box” ของคอมพิวเตอร์ยุคอินเทอร์เน็ตแรกเริ่ม ส่วนหัวใจด้านหน้าแสดงถึงการใช้อินเทอร์เน็ตเพื่อจุดประสงค์ที่ดีทั่วโลก
  • โค้ดจริงด้านหลังเป็นการอ้างอิงถึง Linux โดย Akamai เชื่อมโยงสิ่งนี้ว่าเป็น “ภาษาโอเพนซอร์สของอินเทอร์เน็ต” และเป็นภาษาร่วมที่มุ่งสู่โลกที่ปลอดภัยและเชื่อมโยงกันมากขึ้น
  • อีกตัวอย่างหนึ่งของผู้ที่สนใจเสื้อยืดตัวเดียวกันคือบทความของ Wen Chuan Lee ซึ่งเชื่อมต่อไปยังบทความที่เกี่ยวข้องอีกชิ้น

1 ความคิดเห็น

 
GN⁺ 5 시간 전
ความคิดเห็นบน Hacker News
  • “เสื้ออีกตัวที่ Uniqlo x Akamai ขายในไลน์เดียวกัน มีโค้ดที่เห็นชัดว่าเป็น ดีไซน์ที่ยังไม่เสร็จ
    นึกภาพว่าต้องเอาเสื้อยืดไปคืนเพราะมันทำงานผิดพลาดสิ ตลกดี
    “ทำไมถึงคืนสินค้าคะ/ครับ ไซซ์ไม่พอดีหรือไม่ถูกใจเหรอคะ/ครับ?”
    “ไม่ครับ/ค่ะ บรรทัดที่ 37 มี syntax error เลยรันไม่ได้ แล้วผม/ฉันก็กังวลว่าคนบนถนนจะคิดว่าผม/ฉันกำลังโปรโมตการเขียนสคริปต์ Bash ที่ไม่ปลอดภัยอยู่”

    • ถึงพนักงานฝ่ายบริการลูกค้าของ Uniqlo: ถ้ามีใครพยายามคืนเสื้อด้วยเหตุผลว่าโค้ดคอมพิวเตอร์ที่พิมพ์อยู่มีข้อผิดพลาด ก็ปฏิเสธไป แล้วตอบว่า “ถ้าเป็น script kiddie ตัวจริง ก็น่าจะเห็นข้อผิดพลาดนั้นก่อนซื้อแล้ว”
    • ขาดการประกันคุณภาพขนาดนี้ ทำเอา shell-shocked เลย อย่างน้อยช่วยลง แพตช์ ให้หน่อยได้ไหม?
  • ถ้าชอบอะไรแบบนี้ คุณอาจชอบงานของ Martin Kleppe ด้วย ตัวอย่างเช่น Quine Clock
    https://aem1k.com/qlock/
    ผม/ฉันเคย reverse engineer เป็นเวอร์ชันที่ไม่ obfuscate ไว้เมื่อหลายปีก่อนด้วย
    https://gist.github.com/olooney/a89db3932b089925b71b68d7e9f2...
    เขายังทำ ASCII visualization ดี ๆ ไว้อีกเยอะ
    https://aem1k.com/

    • นั่นเป็น Quine จริง ๆ เหรอ?
      มันน่าประทับใจมากก็จริง แต่ก็ยัง...
  • ฟอนต์ไม่ใช่ Consolas แต่เป็น Roboto Mono
    ที่แปลกกว่านั้นคือ ตัวฟอนต์เองเป็นฟอนต์ monospace ที่ถูกต้อง แต่การจัดตัวพิมพ์บนเสื้อกลับไม่ใช่ มีการใส่ kerning โดยเฉพาะคู่ ‘Iy’ ที่เห็นชัด และตัวอักษรแคบ ๆ อย่าง ‘i’ ดูเหมือนจะใช้พื้นที่แนวนอนน้อยกว่า เดาว่าน่าจะจัดด้วยเครื่องมืออย่าง “optical kerning” ของ InDesign

    • เคยมีใครทำฟอนต์ monospace ที่มี kerning แบบไดนามิกไหม? ก่อนอ่านคอมเมนต์ข้างบน ผม/ฉันไม่เคยคิดถึงไอเดียแปลก ๆ แบบนี้เลย ตอนแรกฟังดูไม่สมเหตุสมผล แต่ลองฟังก่อน
      เหตุผลที่ใช้ฟอนต์ monospace คือมันเข้ากับกริดได้ดี แต่ภายในกริดนั้นก็ยังมีพื้นที่ให้ขยับตัวอักษรไปซ้ายหรือขวาเล็กน้อยได้ และอาจทำให้ฟอนต์ monospace อ่านง่ายขึ้นได้ แน่นอนว่าทุกครั้งที่ตัวอักษรถูกดันไปทางซ้าย พื้นที่ด้านขวาก็จะใหญ่ขึ้น ซึ่งก็มีโอกาสสูงพอ ๆ กันที่จะออกมาแย่มาก
    • น่าจะถูก ผม/ฉันเพิ่ม คำแก้ไข ในบทความแล้ว และอ้างคอมเมนต์นี้ไว้ด้วย
  • เสื้อยืดตัวนี้ดีจริง ๆ มีวิดีโอดี ๆ ที่ดีไซเนอร์ตัวจริงอธิบายขั้นตอนการทำ รวมถึงขั้นตอนที่จงใจ ทำให้ OCR ยาก ด้วย: https://youtu.be/jocGLiecpjU?t=526

    • อาจเร็วกว่าถ้าพิมพ์เองแทนที่จะหาวิธี OCR ให้ความรู้สึกเหมือนตอนคัดโค้ดเกมจาก นิตยสาร COMPUTE! เมื่อ 45 ปีก่อน
      https://archive.org/details/1983-01-compute-magazine/page/96...
    • ผม/ฉันเป็นผู้เขียน ขอบคุณมากสำหรับลิงก์ที่ไม่เคยเห็นมาก่อน ดีใจที่ได้เห็น และก็ดีใจด้วยที่ความยากของ OCR ไม่ได้เป็นปัญหาเฉพาะของผม/ฉัน แต่เป็น การออกแบบโดยเจตนา
    • ดูลิงก์แล้ว แต่หาส่วนที่พูดว่าทำให้ OCR ยากไม่เจอ เขาทำอะไรแน่ที่ทำให้ OCR ยากขึ้น?
    • แต่ OCR ไม่ได้ยากเลย ไม่รู้ว่าบทความจะแบ่งทั้งเซกชันให้เรื่องนั้นทำไม
      บน Samsung S24U ผม/ฉันกดปุ่ม “circle to search” บนหน้าจอหลักค้างไว้เพื่อเปิดอินเทอร์เฟซเครื่องมือ AI แล้วกดค้างที่ข้อความเพื่อคัดลอกทั้งหมดในครั้งเดียว ไม่รู้ชื่อทางการ แต่ใช้เวลาประมาณ 2 วินาที
  • การ OCR สิ่งนี้เป็นฝันร้าย และเป็น benchmark ที่ดีสำหรับพวกที่อ้างตัวว่าเป็น โมเดล OCR/vision ชั้นดี
    แต่ถ้าเอาภาพให้เครื่องมือแบบ agentic ที่ใช้ vision model ดี ๆ อย่าง Claude หรือ GPT รุ่นใหม่ แล้วสั่งให้แบ่งเป็นบรรทัด จากนั้น OCR ทีละบรรทัด ก็น่าจะทำได้ค่อนข้างง่าย
    ผม/ฉันยังสงสัยด้วยว่าสคริปต์นี้เองก่อนถูก obfuscate เขียนด้วย LLM หรือเปล่า ดูเหมือนมีคอมเมนต์เยอะพอสมควร แต่ในกรณีนี้ก็ยังโอเค :)

    • ดูไม่เหมือน LLM เขียน มีหลายอย่างที่สะดุดตา
      มีข้อความแสดงความยินดีทั้งภาษาอังกฤษและญี่ปุ่น และมีอีโมจิหัวใจหนึ่งอัน มีความตั้งใจทำกราเดียนต์จากสีฟ้าอมเขียวไปส้ม แต่ช่วงสีเริ่มจากบล็อก ANSI แล้วไปจบกลางบล็อก 256 สี ทั้งที่สีเทอร์มินัล 256 สีไม่ได้จัดเรียงแบบกราเดียนต์ตั้งแต่แรก อีกอย่างที่ท้ายลูปไม่มี sleep ซึ่งถ้าเป็น LLM น่าจะใส่เพิ่มแบบระวังไว้ก่อน
    • ไม่ได้ยากขนาดนั้น โมเดล OCR อุตสาหกรรม ของเราอ่านได้ถูกต้องตั้งแต่ครั้งแรกด้วยพารามิเตอร์ค่าเริ่มต้น
      ตัวอักษรแยกจากกันได้ง่าย และไม่มีพื้นหลังเชิงโครงสร้างที่ทำให้ตัวอ่านสับสน ต่างจากกรณีอย่างวันหมดอายุบนฝาอะลูมิเนียมของโยเกิร์ต ไม่มี texture คล้ายข้อความที่จะทำให้ผลลัพธ์เละ และฟอนต์ก็สะอาด เป็นมาตรฐาน
    • ครั้งล่าสุดที่คนบนอินเทอร์เน็ตหมกมุ่นกับการ OCR base64 บางอย่างคือเมื่อไม่กี่เดือนก่อน ตอนที่ DoJ เผยแพร่อีเมลจำนวนมากของผู้เสียชีวิตคนหนึ่งออกมา แต่เผยแพร่เป็น PDF แบบ rasterized
      ตอนนี้จำชื่อไม่ได้แล้ว ช่วงนั้นมีเรื่องให้เสียสมาธิเยอะเกินไป
    • ฟีเจอร์คัดลอกข้อความจากภาพของ Safari จัดการส่วน base64 ทั้งหมดของสตริงได้เกือบหมด มีแค่ตัวแรกที่อ่านผิดจาก T เป็น I
      แปลกที่ถ้าพยายามคัดลอกทั้งสตริงรวมถึงส่วน hashbang ประสิทธิภาพจะแย่ลงมาก สงสัยว่าข้างในทำอะไรถึงได้ผลดีขนาดนี้
    • เป็นฝันร้ายจริงเหรอ? ผม/ฉันวางภาพย่อภาพแรกของเสื้อลงใน ChatGPT แล้วมันถอดได้ในครั้งเดียว แถมบอกด้วยว่า สคริปต์ Bash ทำอะไร
  • เรียกการเข้ารหัส base64 ว่า obfuscation เนี่ยนะ
    นึกว่าจะได้เห็นเทคนิค deobfuscation ของ JS เท่ ๆ แต่พูดอย่างสุภาพคือผิดหวังจนบรรยายไม่ถูก และทำวันทั้งวันพังเลย

  • ว้าว ผม/ฉันเห็นเสื้อตัวนั้นในร้านแล้วเคยบอกแฟนว่า “สคริปต์นั่นไม่มีทางทำงานได้จริงหรอก คงเป็นแค่ของตกแต่ง” น่าจะขุดต่ออีกหน่อย

    • พลาดกันได้ง่าย ส่วนใหญ่แล้วเราไม่ได้ใจเย็นพอ ความคิดเลยอยู่ในโหมด autopilot
  • ใช้ได้เลย สิ่งเดียวที่เสียดายเกี่ยวกับสคริปต์นี้คือ น่าจะใส่
    sleep 0.1
    ไว้ในลูปด้วย แบบนั้นเวลามันแสดงผลในเทอร์มินัลจะได้อ่านทันจริง ๆ เทอร์มินัลยุคนี้เลื่อนเร็วเกินไปจนมองไม่ทันว่าข้อความไหลผ่านไปอย่างไร
    ถ้าหน่วงให้เหลือประมาณ รีเฟรช 10Hz ก็น่าจะดูดีมาก

    • งั้นบางทีเราอาจเย็บ แพตช์ แปะลงไปตรงนั้นได้?
  • ขำตรงที่ผู้เขียนลองใช้เครื่องมือ OCR หลายตัวแล้วผลลัพธ์ออกมาไม่คงเส้นคงวา จากนั้นก็ใช้เวลานานแก้ผลลัพธ์ที่ดีที่สุดด้วยมือ แทนที่จะพิมพ์เองไปเลย

    • ผมก็คิดแบบเดียวกัน แต่ผมเป็นคนรุ่นที่โตมากับการนั่งคัดลอก “เกม” จากนิตยสารและหนังสือลงบน คีย์บอร์ดยาง เป็นชั่วโมง ๆ แล้วจากนั้นก็ต้องใช้เวลาอีกหลายชั่วโมงแก้คำที่พิมพ์ผิด
    • ลองเอาไปผ่าน PaddlePaddle OCR แล้วมันจัดการได้สมบูรณ์แบบ
      Google OCR ที่ใช้ผ่าน Google Lens บนมือถือก็ดึงข้อความออกมาได้ค่อนข้างดี แต่ไม่ได้แม่น 100% ถึงอย่างนั้น เวลาที่ใช้แก้น่าจะน้อยกว่าการคัดลอกด้วยมือมาก ไม่รู้ว่าผู้เขียนใช้อะไร แต่ถ้าเขาแชร์ว่าการลอง OCR เป็นอย่างไรก็คงดี และเดาว่าน่าจะลองใช้เครื่องมือ OCR แบบง่าย ๆ
    • ผมใช้เวลาเกือบ 2 นาทีพิมพ์ 4 บรรทัด และยังพลาดไปหนึ่งตัวอักษร
      ถ้าเป็นผมก็คงเลือก OCR แน่นอน ต้องเตรียมพร้อมสำหรับ เสื้อยืด Bash ตัวถัดไปที่จะเจอ
    • ทำให้นึกถึงความเป็นจริงของการทำงานอัตโนมัติในสภาพแวดล้อมองค์กร เป็นเรื่องปกติที่วิศวกรจะใช้เวลากว่า 40 ชั่วโมงเพื่อทำให้งานที่มือใหม่ทำเองได้ใน 10 นาที และต้องทำแค่สัปดาห์ละครั้ง กลายเป็นอัตโนมัติ ดูเหมือนว่า ทำให้เป็นอัตโนมัติทุกอย่าง คืออนาคต
    • “แค่พิมพ์เอา” สำหรับคนทั่วไปแล้วมีโอกาสผิดพลาดมากกว่า
  • อดีตเพื่อนร่วมงานเคยมีเสื้อที่มี โปรแกรม Go อยู่บนเสื้อ ซึ่งผมคิดมาตลอดว่ามันเท่มาก
    [0] https://github.com/GL-Kageyama/UNIQLO_Akamai_T-shirt_Code

    • ไม่แน่ใจว่าหมายถึงโปรแกรมสำหรับเล่น Go หรือหมายถึงภาษา Go ถ้ามีใครทำ โปรแกรม Go ด้วยภาษา Go ก็น่าสนุกดี
    • ปีนี้ผมซื้อเสื้อตัวหนึ่งที่มีโค้ด Go อยู่ ไม่คิดเลยว่ามันเป็นโค้ดจริง นึกว่าเป็นข้อความสุ่ม ๆ เท่านั้น