Computer >> Máy Tính >  >> Lập trình >> Ruby

Đóng gói &mở gói:Hướng dẫn đọc dữ liệu nhị phân trong Ruby

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…

Đóng gói &mở gói:Hướng dẫn đọc dữ liệu nhị phân trong Ruby

Đó 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:

  1. 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ó)
  2. 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)
  3. Đọ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)
  4. 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! 🙂