require "openssl" =begin The code at sec1 was written by yoshikizh. It can be viewed at https://github.com/yoshikizh/ruby_base64. It is available under the MIT license. The code in sec1 has been changed and no longer corresponds to the original code. The code in sec1 is used to decode the base64. The code at sec2 was written by stesla. It can be viewed at https://github.com/stesla/base32. It is available under the MIT license. The code in sec1 has been changed and no longer corresponds to the original code. The code in sec1 is used to decode the base64. The code is used to encode the SHA256 sum into a base32. The rest of the code was written by Marek Küthe and is available under the WTFPL license. =end ## sec1 start CharBase64 = { 0 => "A", 17 => "R", 34 => "i", 51 => "z", 1 => "B", 18 => "S", 35 => "j", 52 => "0", 2 => "C", 19 => "T", 36 => "k", 53 => "1", 3 => "D", 20 => "U", 37 => "l", 54 => "2", 4 => "E", 21 => "V", 38 => "m", 55 => "3", 5 => "F", 22 => "W", 39 => "n", 56 => "4", 6 => "G", 23 => "X", 40 => "o", 57 => "5", 7 => "H", 24 => "Y", 41 => "p", 58 => "6", 8 => "I", 25 => "Z", 42 => "q", 59 => "7", 9 => "J", 26 => "a", 43 => "r", 60 => "8", 10 => "K", 27 => "b", 44 => "s", 61 => "9", 11 => "L", 28 => "c", 45 => "t", 62 => "-", 12 => "M", 29 => "d", 46 => "u", 63 => "~", 13 => "N", 30 => "e", 47 => "v", 64 => "=", 14 => "O", 31 => "f", 48 => "w", 15 => "P", 32 => "g", 49 => "x", 16 => "Q", 33 => "h", 50 => "y" } def i2pjdecode64(str) stra = str.split("") t = 0 stra.each { |n| t += 1 if n == CharBase64[64] } #t.times { stra.pop } stra.pop t strb = [] strc = "" dbase64 = CharBase64.invert stra.each { |n| strb << dbase64[n] } strb.collect! do |n| n.to_s(2).length != 6 ? "0"*(6 - n.to_s(2).length) + n.to_s(2) : n.to_s(2) end if t > 0 tt = strb[strb.size-1] t*2.times{tt.slice!(tt.size-1,1)} strb[strb.size-1] = tt end strb.each{ |n| strc += n } return [strc].pack("B*") end ## sec1 end ## sec2 start module Base32 @table = "abcdefghijklmnopqrstuvwxyz234567".freeze class << self attr_reader :table end class Chunk def initialize(bytes) @bytes = bytes end def encode n = (@bytes.length * 8.0 / 5.0).ceil p = n < 8 ? 5 - (@bytes.length * 8) % 5 : 0 c = @bytes.inject(0) {|m,o| (m << 8) + o} << p [(0..n-1).to_a.reverse.collect {|i| Base32.table[(c >> i * 5) & 0x1f].chr}, ("=" * (8-n))] end end def self.chunks(str, size) result = [] bytes = str.bytes while bytes.any? do result << Chunk.new(bytes.take(size)) bytes = bytes.drop(size) end result end def self.encode(str) chunks(str, 5).collect(&:encode).flatten.join end end ## sec2 end if ARGV.length == 0 $stderr.puts "The base64 should be given as the first argument." end dat = i2pjdecode64(ARGV[0]) puts Base32.encode(OpenSSL::Digest::SHA256.digest dat[0...391]).tr("=", "") + ".b32.i2p"