圧縮アルゴリズム or 暗号アルゴリズム

なぜか文芸的プログラミングを読んでいたら 圧縮か 暗号の勉強をしたくなってきた。
ので可変長ビットいじるものをrubyでなんとなく作ってみた。

class Bit
   include Math
   attr_accessor :value, :bits

   def initialize(value=0, bits=0)
      if bits == 0 and value != 0
         bits = (log(value)/log(2)).to_i+1
      end
      set(bits, value)
   end

   def set(bits, value)
      @bits = bits
      @value= value
   end

   def +(b)
      value = (@value << b.bits) | b.value
      bits  = @bits + b.bits
      Bit.new(value ,bits)
   end

   def <<(bit)
      @bits += bit.bits
      @value <<= bit.bits
      @value |= bit.value
      self
   end

   def each(d = 0, &proc)
      val = @value
      @bits.downto(1) do
         yield(val&1 == 0? 0: 1)
         val = val >> 1
      end
   end

   def to_s
      str = ""
      self.each do |x|
         str = x.to_s + str
      end
      str
   end

   def inspect
      str = to_s
      if str.length > 70
         str = str[0,10] + "..." + str[str.length - 10, 10]
      end
      @bits.to_s + "'b" + str
   end

   def [](idx)
      if idx.class == Range
         i = 0
         str = ""
         self.each do |x|
            i = i + 1
            if idx.member?(i)
               str=x.to_s + str
            end
         end
         str
      elsif idx.class == Fixnum
         (@value & (1 << idx))==0?0:1
      end
   end
end

H = Bit.new(1, 1)
L = Bit.new(0, 1)

ビット長を指定しなかった場合の log使ってるとことかかっこ悪いけど、後で直せたら直そう。
エンディアンも意識してないからCPU orientedだけど、とりあえず論理的なところだけ勉強したいからいいや。
あとdef []()のところってもっといい書き方があるんだろうけれども、今の僕にはわかんない。ここも後で直そう。

とりあえずはできた。実行してみる。

irb(main):001:0> x = Bit.new(255)
=> 8'b11111111
irb(main):002:0> y = Bit.new(0b101010101010)
=> 12'b101010101010
irb(main):003:0> z = Bit.new(1)
=> 1'b1
irb(main):004:0> y.value
=> 2730
irb(main):005:0> y.bits
=> 12
irb(main):006:0> w = x+y+z
=> 21'b111111111010101010101
irb(main):007:0> x << H << H<< L<< H
=> 12'b111111111101
irb(main):008:0> w+w+w+w
=> 84'b1111111110...0101010101

イイっぽい。どっちからはじめようかな。。。