Trong bài viết này, bạn sẽ tìm hiểu về các phương pháp gói &giải nén Ruby!
Nhưng tại sao chúng ta cần những phương pháp này?
Làm việc với văn bản dễ dàng hơn nhiều so với làm việc với dữ liệu nhị phân .
Văn bản cho phép bạn sử dụng:
- biểu thức chính quy
- các phương pháp như
scan
&match
- gsub
Nhưng nếu bạn muốn làm việc với dữ liệu nhị phân, có một số công việc phải làm. Đó là lúc các phương thức giải nén Array # pack &String # phát huy tác dụng.
Hãy để tôi cho bạn xem một số ví dụ, bắt đầu chỉ với một chuỗi đơn giản và sau đó chuyển sang những thứ thú vị hơn.
Chuỗi giá trị ASCII
Điều này sẽ chuyển đổi mọi ký tự trong chuỗi thành giá trị thập phân:
str = "AABBCC" str.unpack("c*") # [65, 65, 66, 66, 67, 67]
Lưu ý "c*"
đối số cho unpack
.
Đây là "chuỗi định dạng" cho biết unpack
phải làm gì với dữ liệu. Trong trường hợp này, c
có nghĩa là lấy một ký tự &chuyển đổi nó thành một giá trị số nguyên (phương thức String # ord cũng thực hiện điều này).
Dấu hoa thị *
chỉ nói "lặp lại định dạng này cho tất cả dữ liệu đầu vào".
Chuyển Hex thành Chuỗi
H
được sử dụng với pack
phương thức cung cấp cho bạn chuyển đổi số hex thành chuỗi.
Ví dụ :
["414243"].pack("H*") # "ABC" "ABC".unpack("H*") # ["414243"]
Cách chuyển Hex sang Số nguyên
Chuỗi định dạng này có 4 byte dữ liệu và trả về một số nguyên. Một điều cần lưu ý là những byte này ở định dạng "little-endian".
Ví dụ :
"\xff\x00\x00\x00".unpack("l").first # 255
"\x90\xC0\xDD\x08".unpack("l").first # 148750480
Tôi đã sử dụng first
ở đây vì unpack
trả về một mảng.
Phân tích cú pháp tệp nhị phân với phương pháp giải nén
Làm cách nào để bạn đọc một tệp nhị phân như EXE, PNG hoặc GZIP?
Nếu bạn đọc những tệp này giống như văn bản thuần túy, bạn sẽ thấy thứ gì đó giống như dữ liệu ngẫu nhiên…
Đó không phải là thứ ngẫu nhiên.
Có một cấu trúc dạng tài liệu cho nhiều định dạng tệp này và unpack
là những gì bạn có thể sử dụng để đọc dữ liệu đó và chuyển đổi nó thành một thứ hữu ích.
Đây là một ví dụ :
binary_data = "\x05\x00\x68\x65\x6c\x6c\x6f" length, message = binary_data.unpack("Sa*") # [5, "hello"]
Trong ví dụ này, dữ liệu nhị phân (được biểu thị bằng hệ thập lục phân, nhỏ gọn hơn 1s &0s) có trường độ dài hai byte (16 bit) chứa độ dài của chuỗi sau. Sau đó là chính chuỗi.
Các tệp nhị phân và giao thức mạng nhị phân có trường “độ dài” là rất phổ biến.
Điều này cho trình phân tích cú pháp biết chính xác bao nhiêu byte sẽ được đọc .
Có.
Tôi biết trong ví dụ này, tôi đã đọc cả độ dài và dữ liệu trong một bước, điều đó chỉ để giữ mọi thứ đơn giản.
Cách sử dụng Gem BinData
Ngoài ra còn có đá quý bindata, được xây dựng đặc biệt để giúp bạn phân tích cú pháp các cấu trúc nhị phân.
Đây là một ví dụ :
class BinaryString < BinData::Record endian :little uint16 :len string :name, :read_length => :len end
Lưu ý read_length
tham số. Điều này sẽ yêu cầu dữ liệu liên kết tính ra độ dài từ trường, vì vậy điều này sẽ giúp bạn tiết kiệm rất nhiều công việc 🙂
Vì vậy, nếu bạn muốn viết một trình phân tích cú pháp cho bất kỳ định dạng nhị phân nào, đây là các bước:
- Tìm thông số kỹ thuật cho định dạng này (nếu nó không được công khai, bạn sẽ phải thiết kế ngược lại, đây là toàn bộ chủ đề của riêng nó)
- Viết lớp `bindata` cho mọi phần của tệp (bạn thường sẽ tìm thấy phần tiêu đề trước với siêu dữ liệu và sau đó là nhiều phần dữ liệu)
- Đọc và xử lý dữ liệu theo cách bạn muốn (ví dụ:trong PNG, bạn có thể thay đổi màu sắc của hình ảnh)
- Lợi nhuận!
Nếu bạn muốn xem một ví dụ đầy đủ về bindata
trong thực tế, hãy xem trình phân tích cú pháp PNG của tôi trên github.
Mã hóa Base64
Có loại mã hóa này được gọi là "Base64". Bạn có thể đã thấy nó trước đây trên một URL.
Trông giống như thế này :
U2VuZCByZWluZm9yY2VtZW50cw==
Dấu bằng kép ở cuối thường là dấu hiệu cho biết bạn đang xử lý Base64
, mặc dù một số đầu vào có thể dẫn đến các dấu bằng không có ở đó (chúng được sử dụng làm phần đệm).
Vậy tại sao tôi lại nói với bạn điều này…
Bên cạnh đó là một điều hữu ích cần biết?
Chà, hóa ra bạn có thể chuyển đổi một chuỗi thành Base64
bằng cách sử dụng pack
phương pháp.
Như bạn có thể thấy ở đây :
def encode64(bin) [bin].pack("m") end encode64 "abcd" # "YWJjZA==\n"
Trên thực tế, đây là phương pháp chính xác được sử dụng trong Base64
mô-đun từ thư viện chuẩn.
Tóm tắt
Trong bài đăng này, bạn đã tìm hiểu về pack
&unpack
các phương pháp này giúp bạn làm việc với dữ liệu nhị phân. Bạn có thể sử dụng điều này để phân tích cú pháp các tệp nhị phân, chuyển đổi một chuỗi thành các giá trị ASCII và để mã hóa Base64.
Đừng quên chia sẻ và đăng ký vì vậy bạn có thể thưởng thức nhiều bài đăng blog như thế này! 🙂