2013-01-12 8 views
3

Ruby에서 왜 배열이 필요한지 Packing? 어떻게합니까 directive 그러한 포장을하는 데 도움이됩니까?루비에서 pack() 및 unpack()은 어떻게 작동합니까?

내 콘솔에서 어떤 코드를 실행하여 배열 패킹에서 지시어가 어떻게 표시되는지 확인했습니다. 그러나 출력은 각 지시문과 거의 동일합니다. 그렇다면 그들은 어떻게 다른가?

irb(main):003:0> n = [ 65, 66, 67 ] 
=> [65, 66, 67] 
irb(main):004:0> n.pack("ccc") 
=> "ABC" 
irb(main):005:0> n.pack("C") 
=> "A" 
irb(main):006:0> n.pack("CCC") 
=> "ABC" 
irb(main):007:0> n.pack("qqq") 
=> "A\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x00\ 
x00\x00\x00" 
irb(main):008:0> n.pack("QQQ") 
=> "A\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x00\ 
x00\x00\x00" 
irb(main):009:0> n.pack("SSS") 
=> "A\x00B\x00C\x00" 
irb(main):010:0> n.pack("sss") 
=> "A\x00B\x00C\x00" 
irb(main):011:0> 

이제 콘솔에서 n.pack("SSS") and n.pack("sss");n.pack("ccc") and n.pack("CCC"); n.pack("qqq") and n.pack("QQQ") 같은 출력을 볼 수 있습니다. 그렇다면 차이점은 무엇입니까?

그리고 실제 제품에서 각 지시어가 작동하는 방식에 대한 예제도 다루지 않았습니다. 나는 아래 지시문을 테스트하는 방법을 모르기 때문에 혼동 스럽습니까? 나를 위해 또한 들이 협조 어떤 작은 코드 :

  • S_, S!
  • S> L> Q>
  • S!< I!<
  • L_, L!

답변

9

당신은 어떻게 컴퓨터 상점 수의 기본 원리에 대한 질문을 요청하고 있습니다 메모리에. 예를 들어, 당신은 자세한 내용을 보려면 다음 볼 수 있습니다 : 예를 들어

http://en.wikipedia.org/wiki/Computer_number_format#Binary_Number_Representation
http://en.wikipedia.org/wiki/Signed_number_representations

Ss의 차이를 가지고; 둘 다 16 비트 숫자의 패킹 및 패킹에 사용되지만, 하나는 부호있는 정수 용이고 다른 하나는 부호없는 용입니다. 이것은 문자열을 원래의 정수로 다시 압축하고자 할 때 중요한 의미가 있습니다.

S 16 비트 부호 수단 번호 0 - 65535 (0 - (2^16-1))
s : 16 비트 정수 번호 -32768 - 32767 (- (2^15) - (2- (1 비트) 부호에 사용하는^15-1))

의 차이는 여기에서 볼 수있다 :

# S = unsigned: you cannot pack/unpack negative numbers 
> [-1, 65535, 32767, 32768].pack('SSSS').unpack('SSSS') 
=> [65535, 65535, 32767, 32768] 

# s = signed: you cannot pack/unpack numbers outside range -32768 - 32767 
> [-1, 65535, 32767, 32768].pack('ssss').unpack('ssss') 
=> [-1, -1, 32767, -32768] 

그래서 당신은 당신이 번호를 이해하기 위해 컴퓨터 메모리에 표현하는 방법을 알고 있어야 참조하여 문제. 부호있는 숫자는 부호를 나타내는 데 1 비트를 사용하지만 부호없는 숫자는이 추가 비트가 필요하지 않지만 음수는 표시 할 수 없습니다.

숫자가 컴퓨터 메모리에서 이진수로 표시되는 방식의 매우 기본적인 내용입니다.

예를 들어 포장해야하는 이유는 한 컴퓨터에서 다른 컴퓨터로 (네트워크 연결을 통해) 숫자를 바이트 스트림으로 보내야하는 경우입니다. 스트림을 통해 전송하려면 정수 숫자를 바이트로 압축해야합니다. 다른 옵션은 숫자를 문자열로 보내는 것입니다. 패킹과 언 패킹 대신 양쪽 끝에서 문자열로 인코딩하고 디코딩합니다.

또는 Ruby의 시스템 라이브러리에서 C 함수를 호출해야한다고 가정 해 보겠습니다. C로 작성된 시스템 라이브러리는 기본 정수 (int, uint, long, short 등) 및 C- 구조체 (struct)에서 작동합니다. 이러한 시스템 메소드를 호출하기 전에 Ruby 정수를 시스템 정수 또는 C- 구조로 변환해야합니다. 그러한 경우 packunpack은 이러한 방법을 인터페이스하는 데 사용할 수 있습니다.


추가 지시어에 대해서는 packed 바이트 시퀀스를 나타내는 방법의 엔디안을 처리합니다. 어떤 엔디안 수단 여기에 참조가 작동하는 방법 :

# Big endian 
> [34567].pack('S>').bytes.map(&:to_i) 
=> [135, 7] 
# 34567 = (135 * 2^8) + 7 

# Little endian 
> [34567].pack('S<').bytes.map(&:to_i) 
=> [7, 135] 
# 34567 = 7 + (135 * 2^8) 
+1

'+ 1' :

단순화 측면에서 http://en.wikipedia.org/wiki/Endianness

가 그냥 정수는 바이트로 변환해야 주문하는 포장 방법을 알려줍니다 당신의 설명에 '무엇과 왜'- 같은 것에 대해 대단히 감사합니다. 그러나 실제 생활에서 어떻게 사용되는지 살펴보기 위해 요청한 지시어에 대한 코드를 제공 할 수 있습니까? 나는 문서 자체에 어떤 코드도 보지 못했기 때문에 결국에는 그것을 시도 할 수 없었다. 그래서 당신의 작은 도움이 저에게 잘 시작하도록 도와 줄 수 있습니다! –

+0

@PythonLikeYOU - 제 편집 참조 – Casper

+0

당신은 마지막 부분을 잘 설명했지만, 제 잘못은 완전히 요컨대 들어 있습니다! : –