Vortex Level0 with Ruby

  • Thread starter Eugeni Akmuradov
  • Start date
E

Eugeni Akmuradov

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.
 
R

Ryan Davis

socket =3D TCPSocket::new( "vortex.labs.overthewire.org", 5842 )
data=3DArray.new
s=3D0
=20
4.times do
data =3D data + socket.recvfrom(4)
end
data.compact!
puts "complete string #{data.inspect}"
data.each { |x| s +=3D x.unpack('L')[0] ; print x.unpack('L')[0], " " = }
puts
socket.write s
puts socket.read
socket.close
=20
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:
class Socket
def self.open(*args) # 'cuz I don't like ugly
f =3D self.class.new(*args)
yield f
f.close
end
end
=20
TCPSocket.open("vortex.labs.overthewire.org", 5842) do |s|
auth =3D s.read(16).unpack("V4").inject { |sum, n| sum + n }
s.write [auth].pack("V")
pass =3D s.read
p pass
end
 
E

Eugeni Akmuradov

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
 
J

Jesús Gabriel y Galán

thanx, but i also dont't get this part

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.
 
R

Ryan Davis

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
 
R

Ryan Davis

thanx, but i also dont't get this part
=20
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.=
 
E

Eugeni Akmuradov

i just need some time :)
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 ?
 
J

Jesús Gabriel y Galán

i just need some time :)
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,201
Latest member
KourtneyBe

Latest Threads

Top