Sha256: 40901ce2cf0d4e50b126731cbb14192767c2dd287fbf8a90907f258b0f2649c8

Contents?: true

Size: 883 Bytes

Versions: 1

Compression:

Stored size: 883 Bytes

Contents

module ROTP
  class OTP
    attr_reader :secret, :digits, :digest

    # Params: secret in base32
    def initialize(s, options = {})
      @digits = options[:digits] || 6
      @digest = options[:digest] || "sha1"
      @secret = options[:raw_secret] ? s : Base32.decode(s)
    end

    def generate_otp(count)
      hmac = OpenSSL::HMAC.digest(
        OpenSSL::Digest::Digest.new(digest),
        secret,
        int_to_bytestring(count)
      )

      offset = hmac[19] & 0xf
      code = (hmac[offset] & 0x7f) << 24 |
        (hmac[offset + 1] & 0xff) << 16 |
        (hmac[offset + 2] & 0xff) << 8 |
        (hmac[offset + 3] & 0xff)
      code % 10 ** digits
    end

    def int_to_bytestring(int, padding = 8)
      result = []
      until int == 0
        result << (int & 0xFF).chr
        int >>=  8
      end
      result.reverse.join.rjust(8, 0.chr)
    end

  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rotp-1.0.0 lib/rotp/otp.rb