Module: BTC::Data

Extended by:
Data
Included in:
BTC, Data
Defined in:
lib/btcruby/data.rb,
lib/btcruby/data.rb

Overview

This allows doing BTC.to_hex(...)

Constant Summary collapse

HEX_PACK_CODE =
"H*".freeze
BYTE_PACK_CODE =
"C*".freeze

Instance Method Summary collapse

Instance Method Details

#bytes_from_data(data, offset: 0, limit: nil, range: nil) ⇒ Object

Converts a binary string to an array of bytes (list of integers). Returns a much more efficient slice of bytes if offset/limit or range are specified. That is, avoids converting the entire buffer to byte array.

Note 1: if range is specified, it takes precedence over offset/limit.

Note 2: byteslice(...).bytes is less efficient as it creates an intermediate shorter string.

Raises:

  • (ArgumentError)


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/btcruby/data.rb', line 55

def bytes_from_data(data, offset: 0, limit: nil, range: nil)
  raise ArgumentError, "Data is missing" if !data
  if offset == 0 && limit == nil && range == nil
    return data.bytes
  end
  if range
    offset = range.begin
    limit  = range.size
  end
  bytes = []
  data.each_byte do |byte|
    if offset > 0
      offset -= 1
    else
      if !limit || limit > 0
        bytes << byte
        limit -= 1 if limit
      else
        break
      end
    end
  end
  bytes
end

#data_from_bytes(bytes) ⇒ Object

Converts binary string to an array of bytes (list of integers).

Raises:

  • (ArgumentError)


81
82
83
84
# File 'lib/btcruby/data.rb', line 81

def data_from_bytes(bytes)
  raise ArgumentError, "Bytes are missing" if !bytes
  bytes.pack(BYTE_PACK_CODE)
end

#data_from_hex(hex_string) ⇒ Object

Converts hexadecimal string to a binary data string.

Raises:

  • (ArgumentError)


22
23
24
25
26
27
28
29
30
# File 'lib/btcruby/data.rb', line 22

def data_from_hex(hex_string)
  raise ArgumentError, "Hex string is missing" if !hex_string
  hex_string = hex_string.strip
  data = [hex_string].pack(HEX_PACK_CODE)
  if hex_from_data(data) != hex_string.downcase # invalid hex string was detected
    raise FormatError, "Hex string is invalid: #{hex_string.inspect}"
  end
  return data
end

#ensure_ascii_compatible_encoding(string, options = nil) ⇒ Object

Returns string as-is if it is ASCII-compatible (that is, if you are interested in 7-bit characters exposed as #bytes). If it is not, attempts to transcode to UTF8 replacing invalid characters if there are any. If options are not specified, uses safe default that replaces unknown characters with standard character. If options are specified, they are used as-is for String#encode method.



91
92
93
94
95
96
97
# File 'lib/btcruby/data.rb', line 91

def ensure_ascii_compatible_encoding(string, options = nil)
  if string.encoding.ascii_compatible?
    string
  else
    string.encode(Encoding::UTF_8, options || {:invalid => :replace, :undef => :replace})
  end
end

#ensure_binary_encoding(string) ⇒ Object

Returns string as-is if it is already encoded in binary encoding (aka BINARY or ASCII-8BIT). If it is not, converts to binary by calling stdlib's method #b.

Raises:

  • (ArgumentError)


101
102
103
104
105
106
107
108
# File 'lib/btcruby/data.rb', line 101

def ensure_binary_encoding(string)
  raise ArgumentError, "String is missing" if !string
  if string.encoding == Encoding::BINARY
    string
  else
    string.b
  end
end

#from_hex(hex) ⇒ Object



42
43
44
# File 'lib/btcruby/data.rb', line 42

def from_hex(hex)
  data_from_hex(hex)
end

#hex_from_data(data) ⇒ Object

Converts binary string to lowercase hexadecimal representation.

Raises:

  • (ArgumentError)


33
34
35
36
# File 'lib/btcruby/data.rb', line 33

def hex_from_data(data)
  raise ArgumentError, "Data is missing" if !data
  return data.unpack(HEX_PACK_CODE).first
end

#random_data(length = 32) ⇒ Object

Generates a secure random number of a given length



17
18
19
# File 'lib/btcruby/data.rb', line 17

def random_data(length = 32)
  SecureRandom.random_bytes(length)
end

#to_hex(data) ⇒ Object



38
39
40
# File 'lib/btcruby/data.rb', line 38

def to_hex(data)
  hex_from_data(data)
end