Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

패킹 및 풀기:Ruby에서 이진 데이터 읽기 가이드

이 기사에서는 Ruby 포장 및 압축 풀기 방법에 대해 알아볼 것입니다!

하지만 이러한 방법이 필요한 이유는 무엇입니까?

텍스트 작업은 바이너리 데이터 작업보다 훨씬 쉽습니다. .

텍스트를 사용하면 다음을 사용할 수 있습니다.

  • 정규 표현식
  • scan과 같은 메소드 &match
  • gsub

그러나 이진 데이터로 작업하려면 몇 가지 추가 작업이 필요합니다. 여기에서 Array#pack 및 String#unpack 메서드가 작동합니다.

간단한 문자열로 시작하여 더 흥미로운 내용으로 넘어가는 몇 가지 예를 보여드리겠습니다.

문자열을 ASCII 값으로

이것은 문자열의 모든 문자를 10진수 값으로 변환합니다:

str = "AABBCC"
str.unpack("c*")

# [65, 65, 66, 66, 67, 67]

"c*" 주목 unpack 인수 .

이것은 unpack을 알려주는 "형식 문자열"입니다. 데이터로 무엇을 할 것인가. 이 경우 c 한 문자를 가져와 정수 값으로 변환하는 것을 의미합니다(String#ord 메서드도 이 작업을 수행합니다).

별표 * "모든 입력 데이터에 대해 이 형식을 반복하십시오"라고만 표시됩니다.

16진수를 문자열로 변환

H pack과 함께 사용 메소드는 16진수를 문자열로 변환합니다.

:

["414243"].pack("H*")
# "ABC"

"ABC".unpack("H*")
# ["414243"]

16진수를 정수로 변환하는 방법

이 형식 문자열은 4바이트의 데이터를 사용하고 정수를 반환합니다. 한 가지 주의할 점은 이러한 바이트가 "리틀 엔디안" 형식이라는 것입니다.

:

"\xff\x00\x00\x00".unpack("l").first
# 255
"\x90\xC0\xDD\x08".unpack("l").first
# 148750480

first를 사용했습니다. unpack하기 때문에 여기에 있습니다. 배열을 반환합니다.

Unpack 방법으로 이진 파일 구문 분석

EXE, PNG 또는 GZIP과 같은 바이너리 파일을 어떻게 읽습니까?

이 파일을 일반 텍스트처럼 읽으면 임의의 데이터처럼 보이는 것을 볼 수 있습니다...

패킹 및 풀기:Ruby에서 이진 데이터 읽기 가이드

무작위가 아닙니다.

문서화된 구조가 있습니다. 이러한 많은 파일 형식 및 unpack 메소드는 해당 데이터를 읽고 유용한 것으로 변환하는 데 사용할 수 있는 것입니다.

예시입니다 :

binary_data     = "\x05\x00\x68\x65\x6c\x6c\x6f"
length, message = binary_data.unpack("Sa*")

# [5, "hello"]

이 예에서 바이너리 데이터(1과 0보다 훨씬 더 간결한 16진수로 표시됨)에는 다음 문자열의 길이가 포함된 2바이트(16비트) 길이 필드가 있습니다. 그런 다음 문자열 자체가 있습니다.

바이너리 파일 및 바이너리 네트워크 프로토콜에 "길이" 필드가 있는 것은 매우 일반적입니다.

읽어야 할 바이트 수를 파서에 정확히 알려줍니다. .

네.

이 예에서 길이와 데이터를 모두 한 단계로 읽는다는 것을 알고 있습니다. 이는 단순하게 유지하기 위한 것입니다.

BinData Gem 사용 방법

바이너리 구조를 구문 분석하는 데 도움이 되도록 특별히 제작된 bindata gem도 있습니다.

예시입니다 :

class BinaryString < BinData::Record
  endian :little
  uint16 :len
  string :name, :read_length => :len
end

read_length 주목 매개변수. 이렇게 하면 bindata가 필드에서 길이를 계산하도록 지시하므로 많은 작업을 절약할 수 있습니다. 🙂

따라서 바이너리 형식에 대한 파서를 작성하려면 다음 단계를 따르십시오.

  1. 이 형식에 대한 사양 찾기(공개되지 않은 경우 리버스 엔지니어링해야 하며 이는 그 자체로 전체 주제임)
  2. 파일의 모든 섹션에 대해 `bindata` 클래스 작성(일반적으로 먼저 메타데이터가 있는 헤더 섹션을 찾은 다음 여러 데이터 섹션을 찾음)
  3. 데이터를 읽고 원하는 대로 처리합니다(예:PNG에서 이미지 색상을 변경할 수 있음)
  4. 이익!

bindata의 전체 예를 보려면 실제로 github에서 내 PNG 파서를 살펴보십시오.

Base64 인코딩

"Base64"라는 인코딩 유형이 있습니다. 이전에 URL에서 본 적이 있을 것입니다.

이렇게 생겼어요 :

U2VuZCByZWluZm9yY2VtZW50cw==

끝에 있는 이중 등호는 일반적으로 Base64를 다루고 있음을 알리는 신호입니다. , 일부 입력은 등호가 없는 결과를 초래할 수 있습니다(패딩으로 사용됨).

그래서 내가 이 말을 하는 이유는...

그 자체로 알아두면 유용한 것 외에도?

문자열을 Base64로 변환할 수 있습니다. pack 사용 방법.

여기에서 볼 수 있듯이 :

def encode64(bin)
  [bin].pack("m")
end

encode64 "abcd"

# "YWJjZA==\n"

사실 이것은 Base64에서 사용되는 정확한 방법입니다. 표준 라이브러리의 모듈입니다.

요약

이 게시물에서 pack에 대해 배웠습니다. &unpack 이진 데이터로 작업하는 데 도움이 되는 메서드. 이것을 사용하여 바이너리 파일을 구문 분석하고 문자열을 ASCII 값으로 변환하며 Base64 인코딩에 사용할 수 있습니다.

공유 및 구독을 잊지 마세요. 이렇게 더 많은 블로그 게시물을 즐길 수 있습니다! 🙂