2009-07-28 29 views
10

Estoy tratando de enviar una serie de bytes binarios a través de un socket, para cumplir con un estándar particular que utiliza mi empresa. Nadie en mi compañía ha usado Ruby para esto antes, pero en otros idiomas, envían los datos a través de un byte a la vez (generalmente con algún tipo de método de "paquete").¿Cómo maneja Ruby bytes/binary?

No puedo encontrar todos modos para crear binarios sobre la marcha, o crear bytes en absoluto (lo más cerca que puedo encontrarlo es cómo convertir una cadena en los bytes que representan sus caracteres).

Sé que puede decir algo como:

@ var = 0b101010101

Pero ¿cómo iba a convertir una cadena de la forma "101010101" o el entero resultante creado cuando lo haga string.to_i (2) en un binario real. Si acabo de enviar la cadena a través de un socket, ¿no enviará el ASCII para "0" y "1" en lugar de los caracteres literales?

Seguramente hay ALGUNA manera de hacer esto de forma nativa en Ruby?

Respuesta

10

Para hacer una cadena que tiene una secuencia arbitraria de bytes, hacer algo como esto:

binary_string = "\xE5\xA5\xBD" 

El "\ x" es un escape especial para codificar un byte arbitraria del hexagonal, por lo que " \ xE5 "significa byte 0xE5.

A continuación, intente enviar esa cadena en el zócalo.

+0

¿Por qué hay algunos "/" en binary_string? – why

+2

Es muy posible que una cadena binaria tenga un byte con valor 0x2F (47). Esa es la codificación ASCII de "/" así que si "inspecciona" la cadena, Ruby generalmente imprimirá un "/". Lo mismo ocurre con cualquier personaje ASCII. Ruby en realidad no sabe si su cadena es una "cadena binaria", para Ruby, su cadena es básicamente una secuencia de bytes (excepto en 1.9 ellos agregaron cierta información de codificación). –

+0

Gracias! me ayuda mucho – why

9

Eche un vistazo al método String.unpack. Este es un ejemplo:

str = "1010" 
str.unpack("cccc") 
=> [49, 48, 49, 48] 

Esto le dará valores enteros. Hay más formas de hacer la conversión.

+0

Antes de editar esta publicación, me habló sobre Array.pack. No entiendo muy bien esto. Si tengo: @bob = ["111111111", "1000", "1111"] o lo que sea, y luego digo: @ bob.unpack (b *), muestra algo así como: "/ 377" ¿Es ese el binario correcto? ¿No es solo el primer elemento de la matriz? ¿Cómo lo haría hacer toda la matriz? – Jenny

+0

Array.pack es lo opuesto a String.unpack. En su ejemplo, bob.pack ('b *') solo empaqueta el primer elemento de la matriz. Probablemente quieras bob.pack ('b * b * b *'). Sin embargo, esto es algo diferente de lo que está pidiendo en la pregunta. – kgiannakakis

14

No sé si esto ayuda lo suficiente, pero puede indexar los bits en un número entero en rubí.

n = 0b010101 

n # => 21 

n = 21 

n[0] # => 1 
n[1] # => 0 
n[2] # => 1 
n[3] # => 0 
n[4] # => 1 
n[5] # => 0 
Cuestiones relacionadas