# coding: utf-8 # https://de.wikipedia.org/wiki/Spaltentransposition class String def clean self.upcase.chars.filter{ |c| c >= "A" && c <= "Z" } end end def encrypt(msg, key) msg, ret, key = msg.clean.join, "", key.clean arr = msg.scan /.{1,#{key.length}}/ arr = arr.map { |a| a.ljust(key.length).chars }.transpose ("A".."Z").each do |c| hits = key.each_index.filter{ |i| key[i] == c } ret += hits.map{ |a| arr[a].join.rstrip }.join end return (ret.scan /.{1,5}/).join(" ") end def decrypt(msg, key) msg, key = msg.clean.join, key.clean rows = (msg.length / key.length.to_f).ceil pad = msg.length % key.length arr, cnt = [], 0 ("A".."Z").each do |c| hits = key.each_index.filter{ |i| key[i] == c } hits.each do |a| p = ((pad != 0) && (a >= pad)) ? rows-1 : rows arr[a] = msg[cnt, p] cnt += p end end return arr.map{ |a| a.ljust(rows).chars }.transpose.join.rstrip end msg = """The Industrial Revolution and its consequences have been a disaster for the human race""" key1 = "uncleted" key2 = "livesinashed" msg = msg.clean.join puts "Original:\t#{msg}" ret = encrypt(encrypt(msg, key1), key2) puts "Encrypted:\t#{ret}" ret = decrypt(decrypt(ret, key2), key1) puts "Decrypted:\t#{ret}" if ret == msg then puts "SUCCESS" end