Vortex Level0 with Ruby

Hello! Recently found this game and it totally got me up. Thou the first
level is extremly straight-forward with C, but i do belive that it is
actually not so difficult with Ruby.
Here is the task:
Your goal is to connect to port 5842 on vortex.labs.overthewire.org and
read in 4 unsigned integers in host byte order. Add these integers
together and send back the results to get a username and password for
level 1.
And here is my code:

require ‘socket’

socket = TCPSocket::new( “vortex.labs.overthewire.org”, 5842 )
data=Array.new
s=0

4.times do
data = data + socket.recvfrom(4)
end
data.compact!
puts “complete string #{data.inspect}”
data.each { |x| s += x.unpack(‘L’)[0] ; print x.unpack(‘L’)[0], " " }
puts
socket.write s
puts socket.read
socket.close

And it do not solve the subject, please help me to understand where i’s
my mistake.

On Dec 6, 2010, at 13:52 , Eugeni A. wrote:

puts
socket.write s
puts socket.read
socket.close

And it do not solve the subject, please help me to understand where i’s
my mistake.

Your code, while ugly, is mostly correct from what I can see. A couple
suggestions:

  1. you’re unpacking with “L”, which is only correct if you’re on the
    same architecture as the server (little endian). You should use “V”
    instead to be portable.

  2. You’re sending back … what? You may want to implement the echo
    server from the TCPServer chapter in the pickaxe to see what’s going on
    exactly.

Here is my solution:

On Tue, Dec 7, 2010 at 9:29 AM, Eugeni A. [email protected]
wrote:

thanx, but i also dont’t get this part

class Socket
def self.open(*args) # 'cuz I don’t like ugly
f = self.class.new(*args)
yield f
f.close
end
end
is it absolutely necessary ?

It’s not necessary. It’s a convenience method (similar to File#open)
so that you don’t need to explicitly close the socket after you are
finished with it. In order to be more robust, the usual thing is to
close the socket in an ensure block, so that even if there’s an
exception, the socket gets closed.

Jesus.

thanx, but i also dont’t get this part

class Socket
def self.open(*args) # 'cuz I don’t like ugly
f = self.class.new(*args)
yield f
f.close
end
end
is it absolutely necessary ?

TCPSocket.open(“vortex.labs.overthewire.org”, 5842) do |s|
auth = s.read(16).unpack(“V4”).inject { |sum, n| sum + n }
s.write [auth].pack(“V”)
pass = s.read
p pass
end

On Dec 7, 2010, at 00:29 , Eugeni A. wrote:

thanx, but i also dont’t get this part

class Socket
def self.open(*args) # 'cuz I don’t like ugly
f = self.class.new(*args)
yield f
f.close
end
end
is it absolutely necessary ?

it is code. on a puzzle. of course it isn’t absolutely necessary. The
important part is that 1) it works and 2) it is a lot cleaner and more
maintainable. I suggest focusing on 1 and applying it to your code. 2
will resolve itself with time.

On Dec 7, 2010, at 00:48 , Jess Gabriel y Galn wrote:

In order to be more robust, the usual thing is to
close the socket in an ensure block, so that even if there’s an
exception, the socket gets closed.

good catch. thanks

i just need some time :slight_smile:
here you basically ovverides the base class for the TCPSocket, and than
creating an instance of that class, which have an modified function open
to close the socket, right ?

On Tue, Dec 7, 2010 at 11:22 PM, Eugeni A.
[email protected] wrote:

i just need some time :slight_smile:
here you basically ovverides the base class for the TCPSocket, and than
creating an instance of that class, which have an modified function open
to close the socket, right ?

In Ruby, classes are open. This means that at any time, you can reopen
the class to do stuff to the class, such as adding methods. Any
instance of that class will have that method available, even the ones
created before the change.

In this case, Ryan is adding a class method that internally creates an
instance of the TCPSocket class, and yields it to a block, ensuring
that after calling the block, the socket is closed.

Jesus.