Forum: Ruby healp reading / writing binary strings.

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Melissa S. (Guest)
on 2007-06-18 05:52
Hey, I'm looking for some help with reading / writing binary string.
Just need some help understanding what exactly is going on..

if I have a string like:
str = "\t\005\001\006\afoo\006\abar"

Or if I have something like:
str =
"\t\025\001\004\001\004\002\004\003\004\004\004\005\004\006\004\a\004\b\004\t\004\n"

What exactly kind of format is that? How do I parse it / read binary
data from it? And how can I write the same type of string from say an
array? ["foo","bar"]?

thanks
Melissa
Robert K. (Guest)
on 2007-06-18 10:56
(Received via mailing list)
On 18.06.2007 03:52, Melissa S. wrote:
> What exactly kind of format is that?
Um, how can we know what format this is?  I mean, you came up with that
string.  The definition above just uses octal escapes.  You can as well
have hex codes:

irb(main):013:0> "\x21\x20\x40"
=> "! @"

 > How do I parse it / read binary
> data from it?

Depends on what you want to do with it.  If you want to access bytes you
can simply do this

irb(main):014:0> s = "\t\001"
=> "\t\001"
irb(main):015:0> s[0]
=> 9
irb(main):016:0> s[1]
=> 1

If you want bits you can do

irb(main):017:0> s.unpack "b*"
=> ["1001000010000000"]
irb(main):018:0> s.unpack "b8b8"
=> ["10010000", "10000000"]
irb(main):019:0> s.unpack "b4*"
=> ["1001"]
irb(main):020:0> s.unpack "b4b4b4b4"
=> ["1001", "1000", "", ""]
irb(main):021:0> s.unpack "b4b4b"
=> ["1001", "1000", ""]
irb(main):022:0> s.unpack "b4b4"
=> ["1001", "1000"]

Please see #unpack docs for more info.

 > And how can I write the same type of string from say an
> array? ["foo","bar"]?

"Write from an array"?  I don't understand what you mean. If you want to
put it into an array, you can simply do

irb(main):023:0> ["foo", "\tbar\n"]
=> ["foo", "\tbar\n"]

Kind regards

  robert
dima (Guest)
on 2007-06-18 10:57
(Received via mailing list)
The string that you can't understand contains the unprintable
characters.
It is probably that you got if from some type of serialization.
You can say that is in a binary format but it's not so good definition
because everything is in binary format - some we can read and some we
can not.

For the second question there is lot of strategies how to store the
array in a file and it most depend what do you want to do latter with
that stored information.
Nowadays is custom to use xml serialization, but you can use YAML or
JSON. They are all human readable.

On Jun 18, 3:52 am, Melissa S. <removed_email_address@domain.invalid>
Melissa S. (Guest)
on 2007-06-18 19:17
Robert K. wrote:
> On 18.06.2007 03:52, Melissa S. wrote:
>> What exactly kind of format is that?
> Um, how can we know what format this is?  I mean, you came up with that
> string.  The definition above just uses octal escapes.  You can as well
> have hex codes:
>
> irb(main):013:0> "\x21\x20\x40"
> => "! @"
>
>  > How do I parse it / read binary
>> data from it?
>
> Depends on what you want to do with it.  If you want to access bytes you
> can simply do this
>
> irb(main):014:0> s = "\t\001"
> => "\t\001"
> irb(main):015:0> s[0]
> => 9
> irb(main):016:0> s[1]
> => 1
>
> If you want bits you can do
>
> irb(main):017:0> s.unpack "b*"
> => ["1001000010000000"]
> irb(main):018:0> s.unpack "b8b8"
> => ["10010000", "10000000"]
> irb(main):019:0> s.unpack "b4*"
> => ["1001"]
> irb(main):020:0> s.unpack "b4b4b4b4"
> => ["1001", "1000", "", ""]
> irb(main):021:0> s.unpack "b4b4b"
> => ["1001", "1000", ""]
> irb(main):022:0> s.unpack "b4b4"
> => ["1001", "1000"]
>
> Please see #unpack docs for more info.
>
>  > And how can I write the same type of string from say an
>> array? ["foo","bar"]?
>
> "Write from an array"?  I don't understand what you mean. If you want to
> put it into an array, you can simply do
>
> irb(main):023:0> ["foo", "\tbar\n"]
> => ["foo", "\tbar\n"]
>
> Kind regards
>
>   robert


Thanks that helps.. Couple more questions..

for this example:
s = "\t\001"
puts s[0] -> 9
How does \t come out as 9? Is that the tab char which in turn is the
number 9 in ascii table?

for this example:
s = "\001"
Ok so now I know this is octal, does the octal value I supply correspond
to the ascii table as well?

for this example:
s = "\x01"
for hex, does the hex value I supply correspond to the ascii table as
well?

Thanks for the help. This is helping me understand this a bunch..

-Melissa
Todd B. (Guest)
on 2007-06-18 20:44
(Received via mailing list)
On 6/18/07, Melissa S. <removed_email_address@domain.invalid> wrote:
> Thanks that helps.. Couple more questions..
>
> for this example:
> s = "\t\001"
> puts s[0] -> 9
> How does \t come out as 9? Is that the tab char which in turn is the
> number 9 in ascii table?

It's just the number 9, but yes you can look at it that way.
irb(main):001:0> 9.chr
=> "\t"

>
> for this example:
> s = "\001"
> Ok so now I know this is octal, does the octal value I supply correspond
> to the ascii table as well?

irb(main):002:0> 1.chr
=> "\001"
irb(main):003:0> 255.chr
=> "\377"
irb(main):004:0> 256.chr
RangeError: 256 out of char range
             from (irb):24:in 'chr'
             from (irb):24
             from :0

(I like that last "from" line :)

> for this example:
> s = "\x01"
> for hex, does the hex value I supply correspond to the ascii table as
> well?

irb(main):005:0> "\x61"
=> "a"
irb(main):006:0> ?a
=> 97

Your bytes are unprintable and so ruby simply tells you the byte
value.  What you do with that value is up to you.
This topic is locked and can not be replied to.