From: Robert Klemme Date: 2007-04-25T01:15:08+09:00 Subject: Re: Best way to create a string with gap (0x00's) in the middle? On 24.04.2007 17:47, Earle Clubb wrote: > I'm trying to build a packet to send to UDPSocket::send. Send requires > a string, but I'm not sure of the best way to build this string. The > packet's structure requires two strings: one beginning at byte 0 and the > other at byte 64. The packet is 128 bytes long and must contain 0's in > the bytes that the strings don't use. Here is an example packet: > > 54 68 69 73 20 69 73 20 73 74 72 69 6E 67 20 41 This is string A > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > 4E 6F 77 20 77 65 20 68 61 76 65 20 73 74 72 69 Now we have stri > 6E 67 20 42 00 00 00 00 00 00 00 00 00 00 00 00 ng B............ > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > > I have a solution, but it's not very elegant and I'm looking for a > better way of doing this. Here's what I have so far: > > I tried this first, but ended up with a bunch of 0x30's where the 0x00's > should be: > > dgram = Array.new(128, 0) > dgram[0] = "This is string A".to_a > dgram[64] = "Now we have string B".to_a > UDPSocket.open.send(dgram.to_s, 0, host, port) > > dgram.to_s converts all of the 0x00's in the array to 0x30's in the > string, which is not acceptable. > > > This is what I have right now: > > dgram = "" > 94.times {dgram << 0} > dgram[0] = "This is string A" > dgram[64] = "Now we have string B" > UDPSocket.open.send(dgram, 0, host, port) > > Like I said: it works, but I don't really like it. Any ideas for a > better implementation? >> %w{foo bar} => ["foo", "bar"] >> %w{foo bar}.pack("a64a64") => "foo\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ 000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000bar\000\000\000\000\000\000\0 00\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0 00\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" Or, printed more nicely: >> %w{foo bar}.pack("a64a64").to_enum(:each_byte).each_slice(16) {|s| puts s.map {|x| "%02x" % x}.join(" ")} 66 6f 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 61 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 => nil Kind regards robert