Mã hóa / Giải mã Base91

Chuyển văn bản hoặc byte nhị phân bằng basE91: 13 bit đầu vào cho mỗi 2 ký tự in được, khiến nó trở thành mã dày đặc nhất trong các mã in được thường dùng — chi phí khoảng 23% so với 33% của Base64. Văn bản được xử lý dưới dạng byte UTF-8; có chế độ byte thập lục phân cho dữ liệu nhị phân. Ngoài ra: Base64 | Base32 / Base58 | Ascii85.
Mọi xử lý diễn ra cục bộ trong trình duyệt của bạn — dữ liệu của bạn không bao giờ được tải lên máy chủ nào.

Chưa từng nghe về Base91? Base91 là gì — giải thích bằng ngôn ngữ đơn giản (có ví dụ mẫu, bảng chữ cái và các bẫy thường gặp).
Cách hoạt động: Đầu vào được chuyển thành byte, rồi đóng gói thành các nhóm 13 bit, mỗi nhóm thành hai ký tự, với một nhóm 14 bit ở chỗ dạng ngắn sẽ bị mơ hồ.
Đầu vào là:
Cách hoạt động: Khoảng trắng bị bỏ qua, và mỗi ký tự được tra trong bảng chữ cái in ở phần dưới trang này. Ký tự không xác định sẽ được báo kèm vị trí.
Đầu ra dưới dạng:
Ctrl+Enter trong ô nhập sẽ chạy chế độ đang chọn.
Chọn Mã hóa hoặc Giải mã rồi nhấn nút thao tác. Bộ tự kiểm chạy 130 vòng mã hóa/giải mã và báo số lượng tại đây.
Bảng chữ cái, in đầy đủ: Base91 không có tổ chức tiêu chuẩn đứng sau, nên bảng chữ cái không được đảm bảo giống nhau giữa các triển khai. Trang này dùng bảng chữ cái của triển khai tham chiếu, và mọi giá trị dưới đây đều được tạo đúng bằng 91 ký tự liệt kê trong bảng.
Các ô màu xanh là ký tự có thể đặt an toàn trong văn bản HTML hoặc chuỗi truy vấn URL; các ô màu cam phải được escape hoặc mã hóa phần trăm (xem ghi chú bên dưới bảng).
Các ô màu xanh là ký tự có thể đặt an toàn trong văn bản HTML hoặc chuỗi truy vấn URL; các ô màu cam phải được escape hoặc mã hóa phần trăm (xem ghi chú bên dưới bảng).
Kích thước đo được trên cùng một đầu vào 92 byte:
Số ký tự đo được tại đây trên chuỗi. Base91 thắng vì 912 = 8281 đủ cho 8192 giá trị của 13 bit, trong khi Base64 phải dùng 4 ký tự chỉ cho 24 bit.
Base91 là gì?

Base91 là cách viết các byte tùy ý chỉ bằng ký tự ASCII in được, cùng việc mà Base64 làm, nhưng nó nhét nhiều bit hơn vào mỗi ký tự. Thay vì cắt đầu vào thành các nhóm 6 bit và in một ký tự cho mỗi nhóm, nó gom bit cho đến khi có ít nhất 13 bit, rồi in hai ký tự cùng biểu thị giá trị của 13 (hoặc 14) bit đó.

Hai ký tự trong bảng chữ cái 91 ký tự có thể biểu thị 91 × 91 = 8281 giá trị khác nhau, và 213 = 8192, nên hai ký tự luôn đủ chỗ cho 13 bit — còn dư 89 giá trị. Đó là toàn bộ mẹo: 13 bit cho mỗi 2 ký tự tương đương 6.5 bit mỗi ký tự, so với 6 bit của Base64, và giảm chi phí khoảng 23% thay vì 33%.

Phiên bản 30 giây: test thành fPNKd, và Hello, World! thành >OwJh>}AQ;r@@Y?F. Giải mã là phép đảo ngược chính xác, và cần đúng bảng chữ cái 91 ký tự này — một bảng chữ cái khác sẽ cho đầu ra khác từ cùng các byte.
Số 13 và 14 bit đến từ đâu

91 × 91 = 8281 giá trị có thể được biểu thị bằng một cặp ký tự, nhiều hơn 213 = 8192 nhưng ít hơn 214 = 16384. Vì vậy một cặp ký tự luôn có thể mang 13 bit, và đôi khi mang 14 bit. Bộ mã hóa thử 13 bit trước: nếu giá trị 13 bit lớn hơn 88 thì nó in giá trị đó thành hai ký tự; nếu không thì nó lấy thêm một bit thứ 14 và in giá trị 14 bit thu được.

Ngưỡng 88 không phải là ngẫu nhiên. Giá trị lớn nhất mà hai ký tự có thể biểu thị là 90 + 91 × 90 = 8280, và 8192 + 89 = 8281 đã vượt quá nó. Vì vậy không nhóm 14 bit nào có cửa sổ 13 bit thấp từ 89 trở lên, nghĩa là bộ giải mã có thể phân biệt hai trường hợp chỉ bằng cách nhìn vào chính giá trị:

Bộ giải mã thấy gìSố bit đã tiêu thụVì sao
value & 8191 là 89 đến 819113 bitGiá trị từ 89 trở lên chỉ có thể đến từ nhánh 13 bit, vì một nhóm 14 bit có cửa sổ 13 bit thấp cao như vậy sẽ phải ít nhất là 8281 — mà không cặp ký tự nào có thể biểu thị.
value & 8191 là 0 đến 8814 bitBộ mã hóa chỉ dự phòng sang 14 bit khi cách đọc 13 bit là 88 hoặc nhỏ hơn, nên nhánh này chỉ là phương án dự phòng và không có gì khác.

Phần còn lại ở cuối — từ 1 đến 13 bit — được in thành một ký tự, cộng thêm ký tự thứ hai khi phần còn lại thực sự cần hơn 7 bit. Đó là lý do độ dài mã hóa tăng theo từng bước hai ký tự và đôi khi kết thúc ở một số lẻ.

Bảng chữ cái, và ba ký tự nó bỏ đi

ASCII in được có 94 ký tự, từ ! (0x21) đến ~ (0x7E). Base91 dùng 91 trong số đó, và ba ký tự bị bỏ là dấu gạch nối -, dấu nháy đơn ' và dấu gạch chéo ngược \. Chữ cái, chữ số và hầu hết dấu câu đều có trong bảng chữ cái đúng một lần, theo thứ tự trong bảng ở trên; ký tự in được thứ 92 đến 94 đơn giản là không thể được đánh địa chỉ.

Vì bảng chữ cái có thứ tự cố định, ký tự cho một giá trị là một phép tra cứu chứ không phải công thức. Hai triển khai sắp xếp bảng chữ cái khác nhau vẫn đều gọi là "Base91" nhưng không đọc được đầu ra của nhau, và đây là nguồn gây kết quả khó hiểu phổ biến nhất. Trang này in bảng chữ cái của mình ra để đầu ra luôn truy ngược được về nó.

Base91 so với các mã hóa in được khác
Mã hóaBit mỗi ký tựKích thước so với đầu vàoGhi chú
Base16 (hex)4200%Hai ký tự cho mỗi byte, đọc được ngay, không cần tra bảng chữ cái.
Base325160%Không phân biệt hoa thường và dễ đọc khi đọc chính tả, nhưng là mã lãng phí nhất trong nhóm.
Base58~5.86~137%Được chọn cho địa chỉ, không phải vì mật độ: nó tránh các ký tự dễ nhầm.
Base646133%Mặc định ở khắp nơi: 4 ký tự cho 3 byte, với 6 bit không dùng của ký tự cuối bị lãng phí.
Ascii85 / Base856.4125%5 ký tự cho 4 byte, không cần bảng tra, nhưng chia cho 85 — xem Công cụ chuyển Ascii85.
Base91~6.5~123%Dày đặc nhất trong các mã này: 13 bit cho mỗi 2 ký tự, đổi lại thỉnh thoảng có nhóm 14 bit.

Các tỷ lệ phần trăm là chi phí tiệm cận của mỗi mã hóa, đã làm tròn; số ký tự đo được cho một đầu vào 92 byte thực tế nằm trong bảng phía trên trang này. Base91 gần với mức tốt nhất mà mọi mã hóa có thể đạt được với ASCII in được: 7 bit mỗi ký tự sẽ cần 128 ký tự khác nhau, mà dải in được không thể cung cấp.

Base91 không phải là gì
  • Không phải tiêu chuẩn. Không có RFC. Triển khai tham chiếu là basE91 0.6.0 của Joachim Henke, phát hành theo giấy phép BSD 3 điều khoản; "Base91" cũng được dùng cho những bảng chữ cái khác không phải bảng này.
  • Không phải mã hóa. Mỗi ký tự chỉ là một phép định hình lại trực tiếp các bit đầu vào, và ai có bảng chữ cái cũng có thể đảo ngược trong một lượt.
  • Không an toàn cho URL. Bảng chữ cái chứa #, %, &, /, ? và ", tất cả đều đổi nghĩa trong URL, nên đầu ra Base91 phải được mã hóa phần trăm trước khi đưa vào chuỗi truy vấn.
  • Không an toàn cho HTML. Nó cũng chứa <, >, & và ", nên chuỗi Base91 đặt vào markup phải được escape bằng Công cụ chuyển thực thể HTML.
  • Không có độ dài cố định. Độ dài đầu ra phụ thuộc vào mẫu bit, không chỉ số byte, nên hai đầu vào cùng kích thước có thể in lệch nhau một ký tự.
Những cái bẫy thực sự gây hại
  • Bảng chữ cái trong trang này là bảng tham chiếu. Nếu công cụ khác cho đầu ra khác với cùng đầu vào, hãy so sánh bảng chữ cái của nó trước khi cho rằng một bên bị lỗi. 91 ký tự phải xuất hiện theo cùng thứ tự.
  • Một ký tự sai có thể làm thay đổi cả phần đuôi. Ranh giới nhóm được quyết định bởi các giá trị đứng trước, nên một chỉnh sửa sớm trong chuỗi làm dịch chuyển mọi thứ sau nó, và phần đuôi chỉ được giải mã bằng các bit thừa của nhóm cuối.
  • Độ dài đầu ra lẻ là bình thường. Điều đó không có nghĩa là chuỗi bị cắt ngắn; nhóm cuối in một ký tự khi giá trị thừa của nó vừa trong 7 bit trở xuống.
  • Một ví dụ đã công bố có thể chứa một ký tự xuống dòng mà bạn không hề gõ. Lệnh shell thêm ký tự kết thúc dòng là lý do thường gặp nhất khiến một giá trị Base91 nổi tiếng dài hơn văn bản tương ứng một ký tự khi mã hóa ở đây: echo "Hello, World!" đưa cho bộ mã hóa 14 byte và in ra >OwJh>}AQ;r@@Y?FF, trong khi 13 byte của riêng văn bản in ra >OwJh>}AQ;r@@Y?F. Cả hai đều đúng, ứng với số byte khác nhau, và số đếm dưới ô đầu ra cho biết bạn đang giữ cái nào.
  • Giải mã dữ liệu nhị phân thành văn bản sẽ không hoạt động. Nếu các byte đã giải mã không phải UTF-8 hợp lệ thì không có văn bản hợp lý nào để hiển thị, và đó là lúc chế độ đầu ra thập lục phân được dùng.
Trả lời nhanh

“Vì sao trang này hiển thị một giá trị khác một ký tự so với công cụ Base91 khác?”

Hầu như luôn là do một bảng chữ cái khác. Nguyên nhân phổ biến thứ hai là một công cụ chỉ dùng nhánh 13 bit mà không bao giờ dùng phương án dự phòng 14 bit; biến thể này gọn hơn trong mã nhưng cho đầu ra khác với thuật toán tham chiếu được dùng ở đây.

Cũng có một trường hợp chính xác có thể xác định bằng cách đếm byte, và nó giải thích ví dụ được trích dẫn rộng rãi nhất: một ký tự xuống dòng ở cuối. Hầu hết các vector đã công bố được tạo bởi một lệnh shell, và shell thêm ký tự kết thúc dòng. 13 byte của Hello, World! in ra 16 ký tự ở đây, còn 14 byte của Hello, World! theo sau bởi một ký tự xuống dòng in ra 17 ký tự >OwJh>}AQ;r@@Y?FF. Dán một trong hai giá trị vào Giải mã: trang này báo số byte, nên có thể phân biệt hai cách đọc thay vì phải tranh cãi. Nút Mẫu tải giá trị phù hợp với người đọc bạn đang dùng, và nó theo công tắc Mã hóa / Giải mã cùng bộ chọn Đầu vào là / Đầu ra dạng: người đọc văn bản nhận giá trị 16 ký tự, người đọc thập lục phân nhận giá trị 17 ký tự với byte 0A cuối cùng hiện rõ, còn bộ mã hóa nhận văn bản cần mã hóa thay vì một chuỗi Base91.

“Base91 có nhỏ hơn Base64 không?”

Có, khoảng 8% về kích thước mã hóa: 13 bit cho mỗi 2 ký tự so với 6 bit cho mỗi ký tự. Với 92 byte văn bản, Base64 in 124 ký tự còn Base91 in 114.

“Tôi có thể giải mã cái này bằng bộ giải mã Base64, hoặc ngược lại không?”

Không. Hai bảng chữ cái trùng nhau ở chữ cái và chữ số, nên bộ giải mã Base64 sẽ chấp nhận một chuỗi Base91 như các ký tự "hợp lệ" và cho ra rác mà không báo lỗi. Hai mã chỉ thống nhất ở hình dạng của sơ đồ.

“Đầu ra có kết thúc bằng phần đệm như Base64 không?”

Không. Base91 không có ký tự đệm nào: các bit thừa ở cuối được in thành nhóm cuối cùng, nên không cần thêm hay bớt gì.

“Làm sao tôi biết kết quả trên trang này là đúng?”

Nhấn Tự kiểm tra 0 đến 64 byte. Công cụ này mã hóa và giải mã 130 mẫu byte bao phủ mọi độ dài mà chỗ tách 13 và 14 bit thay đổi, rồi so sánh các byte trả về với các byte đã đưa vào. Các vector trên nút Mẫu còn được đối chiếu với một triển khai thứ hai được viết cho bộ công cụ kiểm thử của trang này.

Tiêu chuẩn và ghi công

Trang này triển khai thuật toán của bản tham chiếu basE91 (phiên bản 0.6.0) của Joachim Henke, phân phối theo giấy phép BSD 3 điều khoản, với bảng chữ cái đã in ở trên. Giải mã chấp nhận và bỏ qua khoảng trắng, giống như công cụ tham chiếu.

Nội dung trang này được viết riêng cho trang web; thuật toán không được sao chép từ đâu cả. Các giá trị của nút Mẫu là ví dụ duy nhất đi kèm gói tham chiếu (được đánh dấu "ví dụ tham chiếu") cộng với các giá trị do một triển khai thứ hai, độc lập, lưu trong bộ công cụ kiểm thử của trang này tạo ra (được đánh dấu "đối chiếu").