Class: Integer
- Defined in:
- lib/crypto_toolchain/extensions/integer_extensions.rb
Constant Summary collapse
- ROUNDING =
rosettacode.org/wiki/Nth_root#Ruby (with modifications)
%i(up down none)
Instance Method Summary collapse
-
#invmod(n) ⇒ Object
(also: #mod_inverse, #modinv)
From Wikipedia: en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Pseudocode.
- #lrot(num) ⇒ Object
- #modexp(exponent, mod) ⇒ Object (also: #modpow)
- #root(n, round: :down) ⇒ Object
- #rrot(num) ⇒ Object
- #to_bin_string ⇒ Object
- #to_bits(pack_arg = "L>") ⇒ Object
- #to_hex_string ⇒ Object
- #updiv(other) ⇒ Object
Instance Method Details
#invmod(n) ⇒ Object Also known as: mod_inverse, modinv
From Wikipedia: en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Pseudocode
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/crypto_toolchain/extensions/integer_extensions.rb', line 31 def invmod(n) a = self t = 0 new_t = 1 r = n new_r = a while new_r != 0 quotient = r / new_r t, new_t = new_t, (t - quotient * new_t) r, new_r = new_r, (r - quotient * new_r) end raise ArgumentError.new("#{self} is not invertible") if r > 1 t += n if t < 0 t end |
#lrot(num) ⇒ Object
19 20 21 22 |
# File 'lib/crypto_toolchain/extensions/integer_extensions.rb', line 19 def lrot(num) ((self << num) & 0xffffffff) | ((self & 0xffffffff) >> (32 - num)) end |
#modexp(exponent, mod) ⇒ Object Also known as: modpow
76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/crypto_toolchain/extensions/integer_extensions.rb', line 76 def modexp(exponent, mod) raise ArgumentError.new("Exponent must be non-negative") if exponent < 0 product = 1 base = self % mod while exponent > 0 if exponent & 0x01 == 1 product = (product * base) % mod end exponent = exponent >> 1 base = (base**2) % mod end product end |
#root(n, round: :down) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/crypto_toolchain/extensions/integer_extensions.rb', line 52 def root(n, round: :down) raise ArgumentError.new("round must be in [#{ROUNDING.join(', ')}]") unless ROUNDING.include?(round) raise ArgumentError.new("Can't be called on 0") if self == 0 x = self loop do prev = x x = ((n - 1) * prev) + (self / (prev ** (n - 1))) x /= n break if (prev - x) <= 0 end if x**n == self x else case round when :up x+1 when :down x when :none raise ArgumentError.new("#{self} has no #{n}th root") end end end |
#rrot(num) ⇒ Object
24 25 26 27 |
# File 'lib/crypto_toolchain/extensions/integer_extensions.rb', line 24 def rrot(num) ((self & 0xffffffff) >> num) | ((self << (32 - num)) & 0xffffffff) end |
#to_bin_string ⇒ Object
11 12 13 |
# File 'lib/crypto_toolchain/extensions/integer_extensions.rb', line 11 def to_bin_string to_hex_string.from_hex end |
#to_bits(pack_arg = "L>") ⇒ Object
15 16 17 |
# File 'lib/crypto_toolchain/extensions/integer_extensions.rb', line 15 def to_bits(pack_arg = "L>") [self].pack(pack_arg).to_bits end |
#to_hex_string ⇒ Object
3 4 5 6 7 8 9 |
# File 'lib/crypto_toolchain/extensions/integer_extensions.rb', line 3 def to_hex_string ret = to_s(16) if ret.length.odd? ret = "0#{ret}" end ret end |
#updiv(other) ⇒ Object
91 92 93 94 95 96 97 98 |
# File 'lib/crypto_toolchain/extensions/integer_extensions.rb', line 91 def updiv(other) quot, remainder = self.divmod(other) if remainder == 0 quot else quot + 1 end end |