Strange \ n trong chuỗi được mã hóa base64 trong Ruby


159

Thư viện Base64 sẵn có trong Ruby đang thêm một số '\ n'. Tôi không thể tìm ra lý do. Đối với ví dụ đặc biệt này:

irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'base64'
=> true
irb(main):003:0> str =  "1110--ad6ca0b06e1fbeb7e6518a0418a73a6e04a67054"
=> "1110--ad6ca0b06e1fbeb7e6518a0418a73a6e04a67054"
irb(main):004:0> Base64.encode64(str)
=> "MTExMC0tYWQ2Y2EwYjA2ZTFmYmViN2U2NTE4YTA0MThhNzNhNmUwNGE2NzA1\nNA==\n"

\ N nằm ở vị trí cuối cùng và thứ 6 từ cuối. Bộ giải mã (Base64.decode64) trả lại chuỗi cũ một cách hoàn hảo. Điều kỳ lạ là, những thứ này không thêm bất kỳ giá trị nào vào chuỗi được mã hóa. Khi tôi loại bỏ các dòng mới khỏi chuỗi đầu ra, bộ giải mã sẽ giải mã lại một cách hoàn hảo.

irb(main):005:0> Base64.decode64(Base64.encode64(str).gsub("\n", '')) == str
=> true

Thêm vào đó, tôi đã sử dụng một thư viện JS khác để tạo đầu ra được mã hóa base64 của cùng một chuỗi đầu vào, đầu ra không có \ n's.

Đây có phải là một lỗi hoặc bất cứ điều gì khác? Có ai phải đối mặt với vấn đề này trước đây?

FYI,

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]

cùng một vấn đề kỳ lạ ở đây
Nadav B

Câu trả lời:


223

Chỉnh sửa: Vì tôi đã viết câu trả lời này Base64.strict_encode64()đã được thêm vào, không thêm dòng mới.


Các tài liệu hơi khó hiểu, b64encodephương thức được cho là thêm một dòng mới cho mỗi ký tự thứ 60 và ví dụ cho encode64phương thức này thực sự sử dụng b64encodephương thức.

Có vẻ như pack("m")phương thức cho lớp Array được sử dụng bởi encode64cũng thêm các dòng mới. Tôi sẽ coi đó là một lỗi thiết kế mà đây không phải là tùy chọn.

Bạn có thể tự xóa các dòng mới hoặc nếu bạn đang sử dụng đường ray, có ActiveSupport :: CoreExtensions :: Base64 :: Mã hóa bằng encode64sphương thức.


44
Có vẻ như kể từ khi tôi viết câu trả lời này, hiện tại strict_encode64()có vẻ như không thêm dòng mới.
Christoffer Hammarström

15
Thật ngu ngốc! Tại sao bạn làm điều này với tôi, Ruby?
Josh M.

1
Đây là một mặc định assinie, nhưng như @ Christoffer Hammarström đề cập, có một cách để có được một mã hóa b64 thực sự ngay bây giờ.
Dan

1
Rõ ràng điều này tồn tại để duy trì compat ngược với phần mềm không thể xử lý các dòng dài. stackoverflow.com/a/20065991/5749914
Tinh tinh hiếu chiến

115

Trong ruby-1.9.2, bạn có Base64.strict_encode64 không thêm \ n (dòng mới) ở cuối.


Đó là một giải pháp dễ dàng hơn nhiều!
Avishai

Tôi đã kiểm tra Base64.strict_encode64 không được mã hóa đúng ba chuỗi ký tự. như Base64.strict_encode64 ('abc') -> YWJj. ví dụ trên không được mã hóa chính xác.
CodeMaker

9

Vâng, điều này là khá bình thường. Tài liệu đưa ra một ví dụ minh họa việc chia dòng. base64 cũng làm điều tương tự trong các ngôn ngữ khác (ví dụ: Python).

Lý do dòng mới không có nội dung được thêm vào ở giai đoạn mã hóa là do cơ sở 64 ban đầu được nghĩ ra như một cơ chế mã hóa để gửi nội dung nhị phân trong e-mail, trong đó độ dài dòng bị giới hạn. Hãy thoải mái thay thế chúng nếu bạn không cần chúng.


1
Điều này chỉ xảy ra trong Ứng dụng Android của tôi (thư viện Base64 của Java). Tôi đã hoàn toàn bối rối với điều này xảy ra kỳ lạ. Mất 1 tiếng đồng hồ để tìm ra lỗi sai và sau đó tìm kiếm lỗi. Nhận xét này đang giúp hiểu các vấn đề di sản ngay cả sau 6 năm.
burglarhobbit

5

Có vẻ như họ đã bị tước / bỏ qua, như:

Base64.encode64(str).gsub(/\n/, '')

Giải pháp này là bẩn .. còn gì nữa không?
Arnold Roa

1
@yaauie ( thông qua chỉnh sửa được đề xuất ): Các chỉnh sửa tạo ra thay đổi đáng kể thường không nên được thực hiện. Tôi khuyên bạn nên đăng nó như là một câu trả lời riêng biệt.
Pokechu22

3

Sử dụng strict_encode64phương pháp. encode64thêm \ n cứ sau 60 biểu tượng


chúng ta có thể thay đổi nó để thêm sau 76 biểu tượng?
âm thanh

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.