0
0

More than 3 years have passed since last update.

【Ruby】Base64変換ツール書いてみた

Last updated at Posted at 2021-03-08

ここの問題を解いてみました

コード

module Base64
  TABLE = [*"A".."Z", *"a".."z", *"0".."9", "+", "/"]

  module_function

  def encode(str)
    binary_ary = str.bytes.map do |b|
      t = b.to_s(2)
      t.size == 8 ? t : t.rjust(8, "0")
    end

    binary_str = binary_ary.join

    binary_ary  = binary_str.scan(/\d{6}/)
    binary_ary << binary_str[-(binary_str.size % 6)..].ljust(6, "0") unless binary_str.size % 6 == 0

    binary_ary.map { |x| TABLE[x.to_i(2)] }.join << "=" * (binary_ary.size % 4)
  end

  def decode(base_str)
    binary_ary = base_str.delete("=").chars.map do |s|
      t = TABLE.index(s).to_s(2)
      t.size == 6 ? t : t.rjust(6, "0")
    end

    chr_code_ary = binary_ary.join.scan(/\d{8}/).map { |b| b.to_i(2) }
    chr_code_ary.pack("c*")
  end
end

コード(改)

色々ガバかったので改善しました
@scivola さんありがとう

module Base64
  TABLE = [*"A".."Z", *"a".."z", *"0".."9", "+", "/"]

  BIN_TO_CHAR = TABLE.map.with_index.to_h do |char, index|
    ["%06b" % index, char]
  end
  CAHR_TO_BIN = BIN_TO_CHAR.invert

  module_function

  def encode(str)
    binary_str = str.bytes.map { |b| "%08b" % b }.join
    binary_str << "0" * (-binary_str.size % 6)

    base_str = binary_str.gsub(/\d{6}/, BIN_TO_CHAR)

    base_str << "=" * (-base_str.size % 4)
  end

  def decode(base_str)
    unless base_str.size % 4 == 0 && base_str.delete("=").chars.all? { |c| TABLE.include?(c) }
      raise "wrong argument"
    end

    binary_str = base_str.gsub(/./, CAHR_TO_BIN)
    binary_str = binary_str.slice(0..-(binary_str.size % 8 + 1))

    [binary_str].pack("B*").force_encoding("UTF-8")
  end
end

乾燥した感想

解き終わったとき最高に気持ちよかったです
改善点などあればぜひご指摘お願いします

binary_ary << binary_str[-(binary_str.size % 6)..].ljust(6, "0") unless binary_str.size % 6 == 0

ここのunless修飾子以降を書き忘れるという凡ミスを犯し、それに気づくのにめちゃくちゃ時間がかかりました
作業時間の80%は最後の20%の作業にかかる時間であるっていう至言を完全に理解した

0
0
9

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0