Module: Protocol::ZMTP::Z85
- Defined in:
- lib/protocol/zmtp/z85.rb
Overview
Z85 encoding/decoding (ZeroMQ RFC 32).
Encodes binary data in printable ASCII using an 85-character alphabet. Input length must be a multiple of 4 bytes; output is 5/4 the size.
Constant Summary collapse
- CHARS =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#".freeze
- DECODE =
Array.new(128, -1)
- BASE =
85
Class Method Summary collapse
-
.decode(string) ⇒ String
Decodes a Z85-encoded string back to binary data.
-
.encode(data) ⇒ String
Encodes binary data to a Z85-encoded ASCII string.
Class Method Details
.decode(string) ⇒ String
Decodes a Z85-encoded string back to binary data.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/protocol/zmtp/z85.rb', line 47 def self.decode(string) raise ArgumentError, "string length must be a multiple of 5 (got #{string.bytesize})" unless (string.bytesize % 5).zero? out = String.new(capacity: string.bytesize * 4 / 5, encoding: Encoding::BINARY) i = 0 while i < string.bytesize value = 0 5.times do |j| byte = string.getbyte(i + j) d = byte < 128 ? DECODE[byte] : -1 raise ArgumentError, "invalid Z85 character: #{string[i + j].inspect}" if d == -1 value = value * BASE + d end out << ((value >> 24) & 0xFF).chr out << ((value >> 16) & 0xFF).chr out << ((value >> 8) & 0xFF).chr out << (value & 0xFF).chr i += 5 end out end |
.encode(data) ⇒ String
Encodes binary data to a Z85-encoded ASCII string.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/protocol/zmtp/z85.rb', line 24 def self.encode(data) data = data.b raise ArgumentError, "data length must be a multiple of 4 (got #{data.bytesize})" unless (data.bytesize % 4).zero? out = String.new(capacity: data.bytesize * 5 / 4) i = 0 while i < data.bytesize value = data.getbyte(i) << 24 | data.getbyte(i + 1) << 16 | data.getbyte(i + 2) << 8 | data.getbyte(i + 3) 4.downto(0) do |j| out << CHARS[(value / (BASE**j)) % BASE] end i += 4 end out end |