G33k Message
15 Oct 2015This 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