2 điểm bởi GN⁺ 5 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Áo thun thiết kế Akamai bán tại cửa hàng Uniqlo có in mã bash bị làm rối, chạy kết quả của base64 --decode bằng eval, nhưng thực ra đây là một easter egg cho chiến dịch Peace for All
  • Khi giải mã Here string được mã hóa Base64, ta nhận được một script lặp lại việc hiển thị cụm ♥PEACE♥FOR♥ALL♥ trong terminal dưới dạng hoạt ảnh sóng sin
  • Vì Base64 không có sửa lỗi nên việc chép lại khá khó; sau khi kiểm tra padding chuỗi, dấu nháy và dấu ngoặc nhọn có khớp không, tác giả so sánh và tổng hợp kết quả từ Android OCR, Tesseract và Claude
  • Script sau khi giải mã kết hợp tput, bc và mã thoát ANSI 256 màu để tính vị trí ký tự và màu sắc theo kích thước terminal, đồng thời khôi phục con trỏ khi thoát bằng CTRL+C
  • Akamai giải thích đoạn mã thật ở mặt sau có liên hệ với Linux; phông chữ cũng được đính chính từ suy đoán ban đầu là Consolas thành Roboto Mono

Mã có thể chạy ở mặt sau áo thun

  • Mặt trước áo thun Uniqlo x Akamai Peace for All có hình trái tim trong dấu ngoặc nhọn, còn mặt sau in một khối chữ-số lớn
  • Nhìn gần, khối này là mã bash bắt đầu bằng shebang, có cấu trúc giải mã một Here string được mã hóa Base64 bằng base64 --decode rồi chuyển cho eval
  • Bề ngoài có thể trông giống “cách phát tán virus”, nhưng mục đích thực tế là hiển thị thông điệp easter egg
  • Chiếc áo là sản phẩm do Akamai thiết kế nhằm ủng hộ chiến dịch Peace for All của Uniqlo

Quá trình OCR và chép lại

  • Base64 không có cơ chế sửa lỗi, nên để chuyển chuỗi in trên áo thành dạng có thể chạy được cần chép lại hoàn hảo
  • Chuỗi kết thúc bằng phần padding đúng như dự kiến, dấu nháy và dấu ngoặc nhọn cũng khớp, nên nhiều khả năng đây là mã hoàn chỉnh
  • Ba phương pháp được dùng cùng lúc để chép lại
    • OCR tích hợp trong tính năng circle-to-search của Android
    • Tesseract với một số tùy chọn và điều chỉnh
    • OCR và tạo bảng vị trí thông qua Claude
  • Tác giả so sánh ba kết quả bằng diff để tìm các điểm không khớp, rồi xử lý thủ công phần còn lại
  • Một thiết kế áo khác trong cùng dòng Uniqlo x Akamai có vẻ bị cắt từ một khối mã rộng hơn; phần imports bị cắt, return kết thúc thành retu, nên ở trạng thái không thể biên dịch

Cách script bash đã giải mã hoạt động

  • Khi giải mã Base64, một easter egg bash có chú thích đầy đủ xuất hiện
  • Phần đầu script có thông điệp chúc mừng bằng tiếng Anh và tiếng Nhật
    • Congratulations! You found the easter egg! ❤️
    • おめでとうございます!隠されたサプライズを見つけました!❤️
  • Chuỗi dùng cho hoạt ảnh được lặp lại theo dạng ♥PEACE♥FOR♥ALL♥PEACE♥FOR♥ALL...
  • Kích thước terminal được lấy bằng tput cols, tput lines, còn độ dài chuỗi được tính bằng ${#text} của bash
  • Con trỏ được ẩn bằng tput civis; khi nhận SIGINT, script đưa con trỏ trở lại bằng tput cnorm; exit

Cách triển khai hoạt ảnh

  • Vòng lặp chạy liên tục dưới dạng vòng lặp vô hạn for (( t=0; ; t+=1 ))
  • Ở mỗi lần lặp, script lấy từng ký tự từ text để in ra
  • Việc tính vị trí dùng bc -l để tính giá trị sin
    • angle = t * 0.2
    • sine_value = s(angle)
    • x = (cols / 2) + (cols / 4) * sine_value
  • Giá trị x sau khi tính được hiệu chỉnh để không vượt ra ngoài phạm vi terminal: từ 0 đến cols - 1
  • Màu sắc được tính thành gradient trong bảng màu 256 màu, giữa màu cyan tương ứng với 12 và màu orange tương ứng với 208
  • Việc xuất ra màn hình dùng mã thoát ANSI và tput cup để in ký tự đã tô màu tại vị trí chỉ định, rồi xuống dòng để đi dần xuống dưới
  • Kết quả là thông điệp của chiến dịch Peace for All xuất hiện trong terminal dưới dạng vòng lặp sóng sin liên tục

Phông chữ và giải thích thiết kế của Akamai

  • Suy đoán ban đầu về phông chữ là Consolas, nhưng sau khi người dùng Hacker News ralphinus xác nhận, nó được đính chính thành Roboto Mono
  • Các căn cứ cho suy đoán sai gồm số 0 có nét chéo nông, số 1 không có serif, các đường cong tròn của BDyg và chữ số 2
  • Khi ra mắt áo thun, Akamai đã giải thích thông điệp thiết kế trong thông cáo báo chí
  • Màu vàng nâu sáng ám chỉ vỏ nhựa “beige box” của các máy tính thời Internet sơ khai, còn trái tim ở mặt trước thể hiện việc Internet đã được sử dụng cho những mục đích tốt đẹp trên toàn thế giới
  • Đoạn mã thật ở mặt sau là một tham chiếu tới Linux; Akamai liên hệ điều này với “ngôn ngữ nguồn mở của Internet” và một ngôn ngữ chung hướng tới một thế giới an toàn hơn, kết nối hơn
  • Một trường hợp khác cũng quan tâm tới chiếc áo này là bài viết của Wen Chuan Lee, và bài đó dẫn tiếp tới một bài liên quan khác

1 bình luận

 
Ý kiến trên Hacker News
  • “Một chiếc áo khác trong cùng dòng Uniqlo x Akamai có mã rõ ràng là một thiết kế chưa hoàn thiện
    Nghĩ đến cảnh phải trả hàng vì áo thun bị lỗi thật buồn cười
    “Vì sao bạn trả hàng, do không vừa size hay do không thích?”
    “Không, là vì có lỗi cú pháp ở dòng 37 nên nó không chạy được, và tôi lo người đi đường sẽ nghĩ tôi đang cổ xúy cho Bash scripting không an toàn”

    • Gửi nhân viên chăm sóc khách hàng của Uniqlo: nếu có ai định trả áo vì lỗi trong đoạn mã được in lên đó thì hãy từ chối, rồi đáp rằng: “nếu là script kiddie thứ thiệt thì lẽ ra đã phải nhận ra lỗi đó trước khi mua rồi”
    • Chất lượng đảm bảo kém thế này làm tôi đúng là bị shell-shocked. Ít nhất có thể tung ra một bản vá được không?
  • Nếu bạn thích kiểu này thì có thể cũng sẽ thích tác phẩm của Martin Kleppe. Ví dụ như Quine Clock
    https://aem1k.com/qlock/
    Vài năm trước cũng đã có người đảo ngược nó về dạng không bị làm rối
    https://gist.github.com/olooney/a89db3932b089925b71b68d7e9f2...
    Ngoài ra còn có rất nhiều trực quan hóa ASCII tuyệt vời khác
    https://aem1k.com/

    • Cái đó có thực sự là Quine không?
      Rất ấn tượng đấy, nhưng mà vẫn...
  • Phông chữ không phải Consolas mà là Roboto Mono
    Điều lạ hơn là bản thân phông này đúng là phông monospace chuẩn, nhưng cách dàn chữ trên áo thì không phải vậy. Có kerning, đặc biệt dễ thấy ở cặp ‘Iy’, và các ký tự hẹp như ‘i’ trông như chiếm ít chiều ngang hơn. Tôi đoán họ dàn bằng công cụ kiểu “optical kerning” của InDesign

    • Có ai từng tạo ra phông monospace có kerning động chưa nhỉ? Đây là một ý tưởng hơi quái mà tôi chưa từng nghĩ tới trước khi đọc bình luận ở trên. Nghe ban đầu có vẻ vô lý, nhưng hãy nghe tôi nói
      Lý do dùng phông monospace là vì nó bám lưới tốt. Nhưng ngay trong cái lưới đó vẫn có chỗ để đẩy ký tự hơi sang trái hoặc phải một chút, và biết đâu như vậy lại thành một phông monospace dễ đọc hơn. Tất nhiên, khả năng cao là cứ mỗi lần chữ bị đẩy sang trái thì phần trống bên phải sẽ to hơn, dẫn tới kết quả kinh khủng
    • Có vẻ đúng đấy. Tôi đã thêm đính chính vào bài và cũng trích dẫn bình luận này
  • Chiếc áo này thật sự rất hay. Có một video rất tốt trong đó chính nhà thiết kế giải thích quá trình làm ra nó. Video cũng có phần nói về quá trình cố tình làm cho OCR khó hơn: https://youtu.be/jocGLiecpjU?t=526

    • Có khi tự gõ lại còn nhanh hơn đi tìm cách OCR nó. Chắc sẽ giống cảm giác 45 năm trước ngồi chép code game từ tạp chí COMPUTE!
      https://archive.org/details/1983-01-compute-magazine/page/96...
    • Tôi là tác giả bài viết. Đây là link tôi chưa từng thấy, cảm ơn rất nhiều. Thấy cái này làm tôi vui, và cũng mừng vì việc OCR khó không chỉ là vấn đề của riêng tôi mà là chủ ý trong thiết kế
    • Tôi xem link rồi nhưng không thấy đoạn nào nói rằng họ làm cho OCR khó hơn. Cụ thể họ đã làm gì để OCR trở nên khó vậy?
    • Mà thật ra OCR đâu có khó. Tôi cũng không hiểu vì sao bài viết lại dành hẳn cả một mục cho phần đó
      Trên Samsung S24U, tôi chỉ cần giữ nút “circle to search” ở màn hình chính để mở giao diện công cụ AI, rồi nhấn giữ vào văn bản và sao chép toàn bộ trong một lần. Tôi không biết tên chính thức của nó là gì, nhưng mất cỡ 2 giây
  • OCR cái này đúng là ác mộng, và là một bài benchmark hay cho những thứ tự nhận là mô hình OCR/thị giác giỏi
    Tuy vậy, nếu đưa hình cho một công cụ kiểu agent có gắn mô hình thị giác tốt như Claude hay GPT đời mới, rồi bảo nó chia theo từng dòng và OCR từng dòng riêng, thì có vẻ sẽ khá dễ
    Tôi cũng tò mò không biết bản thân script này trước khi bị làm rối có phải do LLM viết không. Có vẻ có khá nhiều chú thích, nhưng trong trường hợp này thì cũng ổn :)

    • Trông không giống do LLM viết. Có vài điểm khá nổi bật
      Lời chúc mừng xuất hiện cả bằng tiếng Anh lẫn tiếng Nhật, và có một emoji trái tim. Có chủ ý tạo gradient từ xanh ngọc sang cam, nhưng dải này lại bắt đầu từ khối ANSI và kết thúc giữa chừng trong khối 256 màu, trong khi màu terminal 256 vốn không được sắp theo dạng gradient. Ngoài ra ở cuối vòng lặp cũng không có sleep, mà nếu là LLM thì có lẽ nó đã thêm vào theo kiểu phòng thủ
    • Không khó đến thế đâu. Mô hình OCR công nghiệp của bọn tôi đọc chính xác ngay lần thử đầu tiên với tham số mặc định
      Các ký tự tách biệt rất rõ, và không có nền cấu trúc nào gây nhiễu cho bộ đọc. Ví dụ không giống kiểu hạn sử dụng trên nắp nhôm hộp sữa chua. Cũng không có texture kiểu gần-giống-văn-bản để làm rối kết quả, và phông chữ thì sạch sẽ, tiêu chuẩn
    • Lần gần nhất dân mạng bị ám ảnh vì phải OCR một đoạn base64 là mấy tháng trước. Khi đó DoJ tung ra hàng loạt email của một người đã chết, nhưng lại phát hành dưới dạng PDF raster hóa
      Giờ tôi không nhớ tên người đó là ai nữa. Dạo này có quá nhiều chuyện hút hết sự chú ý
    • Tính năng sao chép chữ từ hình ảnh của Safari xử lý gần như trọn vẹn phần base64 của chuỗi đó. Chỉ sai ký tự đầu tiên, đọc T thành I
      Lạ là nếu cố sao chép toàn bộ chuỗi, kể cả phần hashbang, thì hiệu năng tệ hơn hẳn. Không biết bên trong nó làm gì mà lại tốt đến vậy
    • Thật sự là ác mộng à? Tôi dán ảnh thu nhỏ đầu tiên của chiếc áo vào ChatGPT, nó giải được ngay một phát, còn giải thích luôn script Bash đó làm gì
  • Gọi mã hóa base64 là làm rối mã à
    Tôi đã mong đợi mấy kỹ thuật gỡ rối JS ngầu lòi, nên nói nhẹ thì là thất vọng không diễn tả nổi và cả ngày của tôi coi như hỏng

  • Ôi, tôi đã thấy chiếc áo đó trong cửa hàng và nói với bạn gái rằng “cái script đó đời nào chạy thật được, chắc chỉ để trang trí thôi”. Đáng lẽ tôi nên đào sâu hơn

    • Rất dễ bỏ lỡ. Phần lớn thời gian chúng ta không thật sự bình tĩnh, nên suy nghĩ ở trạng thái tự động lái
  • Ổn đấy. Điều duy nhất tôi thấy tiếc ở đoạn script là giá như họ chèn
    sleep 0.1
    vào trong vòng lặp. Làm vậy thì khi in ra trên terminal, người ta còn có thể đọc được. Terminal hiện đại cuộn quá nhanh nên không thể nhìn thấy thông điệp lướt qua
    Làm chậm xuống khoảng cập nhật 10Hz thì sẽ trông rất đẹp

    • Vậy thì biết đâu còn có thể khâu thêm một bản vá vào đó?
  • Tôi thấy buồn cười khi tác giả thử đủ loại công cụ OCR, kết quả thì lúc tốt lúc dở, rồi cuối cùng lại ngồi sửa tay rất lâu bản output tốt nhất, thay vì cứ tự gõ luôn

    • Tôi cũng nghĩ y như vậy. Nhưng tôi thuộc thế hệ lớn lên cùng việc ngồi chép lại hàng giờ những “trò chơi” in trên tạp chí và sách bằng bàn phím cao su. Sau đó lại mất thêm mấy tiếng để sửa lỗi gõ sai nữa
    • Tôi đã chạy thử bằng PaddlePaddle OCR và nó xử lý hoàn hảo
      Google OCR dùng qua Google Lens trên điện thoại cũng trích xuất khá tốt, dù không chính xác 100%. Dù vậy, chắc chắn thời gian sửa vẫn ít hơn rất nhiều so với gõ tay. Tôi không biết tác giả đã dùng gì, nhưng giá như họ chia sẻ đã thử OCR ra sao; có lẽ họ chỉ dùng một công cụ OCR đơn giản
    • Gõ 4 dòng mà mất gần 2 phút, lại còn sót một ký tự
      Nếu là tôi thì tất nhiên cũng sẽ chọn OCR. Phải chuẩn bị cho lần tới gặp một chiếc áo thun Bash nữa chứ
    • Làm tôi nhớ đến thực tế tự động hóa công việc trong môi trường doanh nghiệp. Chuyện các kỹ sư bỏ hơn 40 giờ để tự động hóa một việc mà người mới chỉ mất 10 phút làm tay và lại chỉ cần mỗi tuần một lần là chuyện rất thường thấy. Có vẻ cứ tự động hóa bằng mọi giá mới là tương lai
    • “Cứ gõ thôi” với người bình thường có lẽ còn dễ phát sinh nhiều lỗi hơn
  • Một đồng nghiệp cũ của tôi từng có một chiếc áo in chương trình Go, và tôi luôn thấy nó khá ngầu
    [0] https://github.com/GL-Kageyama/UNIQLO_Akamai_T-shirt_Code

    • Tôi không chắc họ đang nói đến trình giải bằng Go hay là ngôn ngữ Go. Ai đó mà làm một chương trình Go bằng Go thì chắc vui lắm
    • Năm nay tôi cũng mua một cái có in mã Go. Tôi hoàn toàn không nghĩ đó là mã thật, cứ tưởng chỉ là nội dung ngẫu nhiên thôi