Module: Shugoi::Utils

Defined in:
lib/shugoi/utils.rb

Class Method Summary collapse

Class Method Details

.base36_decode(str) ⇒ Object



38
39
40
# File 'lib/shugoi/utils.rb', line 38

def base36_decode(str)
  str.to_s.to_i(36)
end

.base36_encode(num) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/shugoi/utils.rb', line 26

def base36_encode(num)
  return "0" if num.zero?
  alphabet = "0123456789abcdefghijklmnopqrstuvwxyz"
  out = +""
  n = num
  while n.positive?
    n, r = n.divmod(36)
    out.prepend(alphabet[r])
  end
  out
end

.escape_json_string(s) ⇒ Object



81
82
83
# File 'lib/shugoi/utils.rb', line 81

def escape_json_string(s)
  JSON.generate(s.to_s)[1..-2]
end

.hmac_hex(secret, payload) ⇒ Object



18
19
20
# File 'lib/shugoi/utils.rb', line 18

def hmac_hex(secret, payload)
  OpenSSL::HMAC.hexdigest("SHA256", secret.to_s, payload.to_s)
end

.leading_zero_bits(hex_digest) ⇒ Object

Nombre de bits à zéro en tête du digest hex (parité avec la fonction JS bits).



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/shugoi/utils.rb', line 43

def leading_zero_bits(hex_digest)
  leading = 0
  hex_digest.each_char do |c|
    nib = c.to_i(16)
    if nib.zero?
      leading += 4
      next
    end
    leading += nib.to_s(2).match(/^0*/)[0].length
    break
  end
  leading
end

.now_msObject



57
58
59
# File 'lib/shugoi/utils.rb', line 57

def now_ms
  (Time.now.to_f * 1000).to_i
end

.now_secObject



61
62
63
# File 'lib/shugoi/utils.rb', line 61

def now_sec
  Time.now.to_i
end

.secure_equals(a, b) ⇒ Object

Comparaison constant-time de deux hex strings.



12
13
14
15
16
# File 'lib/shugoi/utils.rb', line 12

def secure_equals(a, b)
  return false unless a.is_a?(String) && b.is_a?(String)
  return false unless a.bytesize == b.bytesize
  OpenSSL.fixed_length_secure_compare(a, b)
end

.sha256_hex(str) ⇒ Object



22
23
24
# File 'lib/shugoi/utils.rb', line 22

def sha256_hex(str)
  OpenSSL::Digest::SHA256.hexdigest(str.to_s)
end

.unicode_encode(code) ⇒ Object

Encodage unicode (parité Node). Le module Node encode avec charCodeAt(i) qui donne le CODE UNIT UTF-16 (0-65535) — pour les caractères non-BMP (émojis…), charCodeAt produit DEUX unités (surrogate pair). Ruby each_codepoint donnerait le code point complet (> 65535) → désynchronisation avec le décodage navigateur codePointAt(0). On encode donc par code unit UTF-16, exactement comme JS charCodeAt. Le guard-detect (raw=1) peut être en ASCII-8BIT (bytes obfusqués > 0x7F) : on force une conversion UTF-8 avec remplacement, comme le fetch().text() du module Node.



72
73
74
75
76
77
78
79
# File 'lib/shugoi/utils.rb', line 72

def unicode_encode(code)
  str = code.dup.force_encoding(Encoding::UTF_8)
  str = str.encode(Encoding::UTF_16LE, invalid: :replace, undef: :replace, replace: "\uFFFD")
  str.bytes.each_slice(2).map do |lo, hi|
    unit = lo | (hi << 8)
    (917504 + unit).chr(Encoding::UTF_8)
  end.join
end