Forum: Ruby Ruby-newbie

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.
78a7b26da95c38121116ab20ff2c2753?d=identicon&s=25 Terje Haarstad (eugynon)
on 2009-02-12 13:30
Hi!
Ive been trying for a couple of days to get connected to vortex wargame
with the help of ruby. Since this language is kinda new to me i dont get
what im doing wrong.
The mission is to get 4 unsigned integer, sum them together and send
the answer to server, but the output i get is:
-------------------------------------------------
639805687
passordet er îYYÙ{g6ûbzzzt, wrong
Koplet fra vortex.labs.pulltheplug.org
>Exit code: 0
-------------------------------------------------
Okey, i get the wrong code but why the chars just before?

require 'socket'
host = 'vortex.labs.pulltheplug.org'
port = 5842

s = TCPSocket.new(host, port)
buff = s.recvfrom(16)[0].chomp.unpack("I*")
sum = buff[0].to_i + buff[1].to_i + buff[2].to_i + buff[3].to_i
svar = [sum].pack("I")
s.puts (svar)
passwd = s.recvfrom(128)
puts "passordet er #{passwd}"
s.close
puts "Koplet fra #{host}"
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2009-02-12 14:11
Terje Haarstad wrote:
> require 'socket'
> host = 'vortex.labs.pulltheplug.org'
> port = 5842
>
> s = TCPSocket.new(host, port)
> buff = s.recvfrom(16)[0].chomp.unpack("I*")

This is strange code. If you want to read 16 bytes, just do s.read(16).

Then to see what buff is at this point you should add:

puts "buff = #{buff.inspect}"

#or to see in hex:

puts buff.unpack("H*").first

> sum = buff[0].to_i + buff[1].to_i + buff[2].to_i + buff[3].to_i

puts "sum = #{sum.inspect}"

> svar = [sum].pack("I")

puts "svar = #{svar.inspect}"

> s.puts (svar)

Beware that puts() may add a newline; if that's not wanted, use write()
or print() instead.

> passwd = s.recvfrom(128)

recvfrom is normally only used for UDP sockets. s.read(128) is probably
want you want, as long as you know the server will definitely return 128
bytes and/or close the socket. Or maybe you want s.gets to get upto a
newline.

s.readpartial(128) will wait for at least 1 byte and then return however
many are available; but there's no guarantee that the server will send
its entire response in one chunk.

> puts "passordet er #{passwd}"
> s.close
> puts "Koplet fra #{host}"

...

> Okey, i get the wrong code but why the chars just before?

Well, it looks like that's what the server returned to you. If you have
any questions about the protocol, you'll have to talk to the people who
implement or design the protocol, or look at the protocol documentation.

However when I try this using telnet, I see ~16 bytes of test data, then
when I send my response I just get "bzzzt, wrong". So I think your
problem is using recvfrom when you should be using read.
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2009-02-12 14:16
require 'socket'
host = 'vortex.labs.pulltheplug.org'
port = 5842

s = TCPSocket.new(host, port)
buff = s.read(16).unpack("I*")
sum = buff[0] + buff[1] + buff[2] + buff[3]
svar = [sum & 0xffffffff].pack("I")
s.write(svar)
passwd = s.read(128)
puts "passordet er #{passwd}"
s.close
puts "Koplet fra #{host}"
78a7b26da95c38121116ab20ff2c2753?d=identicon&s=25 Terje Haarstad (eugynon)
on 2009-02-12 17:00
thanks for reply mate!
it made a few things clearer although i
got a few more questions.

Brian Candler wrote:
> require 'socket'
> host = 'vortex.labs.pulltheplug.org'
> port = 5842
>
> s = TCPSocket.new(host, port)
> buff = s.read(16).unpack("I*")
> sum = buff[0] + buff[1] + buff[2] + buff[3]
> svar = [sum & 0xffffffff].pack("I")

Why do u have to use sum & 0xffffffff? an error occour
(`pack': bignum too big to convert into `unsigned long' (RangeError)
from vortex0.rb:16) if i DONT use 0xfffffffff while use s.gets
but why do they conflict with each other?

> s.write(svar)
> passwd = s.read(128)
> puts "passordet er #{passwd}"
> s.close
> puts "Koplet fra #{host}"

again, thanks for helping me out with this great answer!
-terje
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2009-02-15 21:54
Terje Haarstad wrote:
>> sum = buff[0] + buff[1] + buff[2] + buff[3]
>> svar = [sum & 0xffffffff].pack("I")
>
> Why do u have to use sum & 0xffffffff? an error occour
> (`pack': bignum too big to convert into `unsigned long' (RangeError)
> from vortex0.rb:16) if i DONT use 0xfffffffff while use s.gets
> but why do they conflict with each other?

Ruby numbers don't wrap around - they can grow indefinitely large.

Sometimes the four random 32-bit numbers add up to a 33-bit number. In
this case, the server is expecting you to truncate the result to 32
bits. If you don't truncate explicitly, Array#pack will abort because
the number you're asking it to fit into a 32-bit space is too big.

HTH,

Brian.
This topic is locked and can not be replied to.