G33k Message

This problem in ECTF-Teaser 2015 ( \o/ ) was the brainchild of ajithps and was regarded as a ‘cute’ encryption technique by one of the teams participating.

We used Seven Segmented Display wherein we took advantage of the fact that an LED display has 7 components and 2**7(128) is the ASCII character limit. Hence we first convert an alphabet to ASCII and write it in binary form. We check which bits are set and which aren’t and depending on the same generate a display such that if the bit is set, then the LED ‘glows’.

Here are the code snippets for encryption and decryption:

Encryption

# Authors chinmay_dd, skarthik

# Clears global bit arrays
def clear_bit_arrays
	$a_bit = []
	$b_bit = []
	$c_bit = []
	$d_bit = []
	$e_bit = []
	$f_bit = []
	$g_bit = []
end

# Prints out seven segment equivalent of characters(26) present in global arrays
def print_led
	$a_bit.each do |i|
		print ' '
		print i=='1'? '_':' '
		print '  '
	end
	puts 
	for i in 0..$a_bit.size-1
		print $f_bit[i]=='1'? '|':' '
		print $g_bit[i]=='1'? '_':' '
		print $b_bit[i]=='1'? '|':' '
		print ' '
	end
	puts
	for i in 0..$a_bit.size-1
		print $e_bit[i]=='1'? '|':' '
		print $d_bit[i]=='1'? '_':' '
		print $c_bit[i]=='1'? '|':' '
		print ' '
	end
	print "\n\n"
end

# Appends binary representation of a number to global arrays
# Params:
# +bin+:: binary representation of a number
def append_to_arrays(bin)
	$a_bit << bin[0]
	$b_bit << bin[1]
	$c_bit << bin[2]
	$d_bit << bin[3]
	$e_bit << bin[4]
	$f_bit << bin[5]
	$g_bit << bin[6]	
end

# Encrypts string in seven segment display form
# Params:
# +string+:: string of characters read from file to be encrypted
def encrypt(string)
	string_chars = string.scan(/.{1,26}/)

	string_chars.each do |str|
		str.each_char do |i|
			bin = i.unpack("B*")[0][1..-1]
			append_to_arrays(bin)
		end
		print_led
		clear_bit_arrays	
	end
end

# Returns file object of the file from which the flag is to be read
def read_file
	File.new('flag.txt', 'r')
end

#################
# Main function #
#################

f = read_file
clear_bit_arrays
while (line = f.gets)
	
	# Encrypt each line
    encrypt(line)
end

Decryption

# Author @skarthik, @chinmay_dd

# Clears global bit arrays
def clear_bit_arrays
	$a_bit = []
	$b_bit = []
	$c_bit = []
	$d_bit = []
	$e_bit = []
	$f_bit = []
	$g_bit = []	
end

# Computes equivalent value of the ASCII as per encryption and prints character
def print_equivalent_chr
	for idx in 0..$a_bit.size-1
		num = (2**6 * $a_bit[idx]) + (2**5 * $b_bit[idx]) + (2**4 * $c_bit[idx]) + (2**3 * $d_bit[idx]) + (2**2 * $e_bit[idx]) + (2**1 * $f_bit[idx]) + (2**0 * $g_bit[idx])
		print num.chr
	end
	clear_bit_arrays
end

# Takes an input and line counter as a parameter and decrypts given text into plaintext ASCII and prints it using print_equivalent_chr
# Params:
# +string+:: String to be decrypted. It may consist of '|', '_' and ' '
# +counter+:: Counter used to recognize the which level of the 7 segment display is to be decrypted
def decrypt(string, counter)
	# Take 4 characters, equivalent to width of a an ASCII character
	string_div = string.scan(/.{4}/)

	mod = counter%4
	case mod
	when 0
		string_div.each do |read|
			if read[1] == '_' then $a_bit << 1 else $a_bit << 0 end
		end
	when 1
		string_div.each do |read|
			if read[0] == '|' then $f_bit << 1 else $f_bit << 0 end
			if read[1] == '_' then $g_bit << 1 else $g_bit << 0 end
			if read[2] == '|' then $b_bit << 1 else $b_bit << 0 end
		end
	when 2
		string_div.each do |read|
			if read[0] == '|' then $e_bit << 1 else $e_bit << 0 end
			if read[1] == '_' then $d_bit << 1 else $d_bit << 0 end
			if read[2] == '|' then $c_bit << 1 else $c_bit << 0 end			
		end
	when 3
		print_equivalent_chr
	end
end

# Returns a file object from which encrypted text is to be read
def read_file
	File.new('ans.txt', 'r')
end

#################
# Main function #
#################

f = read_file
clear_bit_arrays
counter = 0

while (line = f.gets)

	# Decrypt each line
    decrypt(line, counter)
    counter+=1
end