import socket
import itertools
import struct
import string
import sys


def send_data( rsocket, data ):
	length = struct.pack('I',len(data))
	rsocket.send(length)
	return rsocket.send(data)


def recv_data( rsocket, data ):
	length = struct.unpack('I',rsocket.recv(4))[0]
	data = rsocket.recv(length)
	return length


def purge_candidate_strings( candidate_strings, min_len ):
	return filter( lambda x: len(x)>=min_len, candidate_strings)


candidate_strings = ['']

if len(sys.argv) >= 2:
	candidate_strings = [sys.argv[1]]

charset = 'abcdefghijklmnopqrstuvwxyz_'
multiplier = 4
perm_len = 1
max_len = 0
rsocket = socket.create_connection(("127.0.0.1",4433))
nonce  = rsocket.recv(8)

while max_len < 20:
	num_candidates = len(candidate_strings)
	for i in range(0,num_candidates):
		min_ret_bytes = -1
		possible_candidates = []
		data = ''
		for possible_candidate in map( lambda x : candidate_strings[i]+x ,charset):
			send_data(rsocket, possible_candidate * (1 if max_len >= 4 else 4)  )
			possible_candidates.append((possible_candidate,	recv_data(rsocket, data) ))

	min_len = min(  map( lambda x: x[1], possible_candidates) )
	possible_candidates,_ = zip(*filter( lambda x: x[1] == min_len  , possible_candidates ))
	candidate_strings += possible_candidates
	max_len =  max(map(len,candidate_strings))
	candidate_strings = purge_candidate_strings( candidate_strings, max_len )
	print candidate_strings