z85 0.5 → 0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/ext/z85/z85.c +15 -46
  3. data/lib/z85/version.rb +1 -1
  4. data/lib/z85.rb +41 -5
  5. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc3a06cd55838caabe94e5669cb0a28d4279f12b9b26e4e78aaf692789b2a24a
4
- data.tar.gz: 6b3662ea29821bbb38b0f813b20790f22ad08da30b5bc3a51fe80038b289bf7e
3
+ metadata.gz: ebd3df9b05fe5482e386d7940d6ba1c08c6d24d46aa01a65894ca7911f4d94f9
4
+ data.tar.gz: 40edd0c27fbc90cec3f897bfff9b6ee07ce83435046c87b41074f363d5534e52
5
5
  SHA512:
6
- metadata.gz: 6a0674ef043853bdf233ccef0dd6536d92469a7f6bad6fdc8929c5dfcd6991dd03dc8f3d377f64f7c98035059ed0abebf85b0c1980e014548f6beba34c10a68f
7
- data.tar.gz: c1a1cdacb3348191524c0ce6ee376282abca80c26067639a50329765cf25226758067d575362c740063f7ee8f721ebebd1e4994cbd86af2bd797212d6e6c0849
6
+ metadata.gz: b6ba69e691cbf272a2ae65beca2a074fa21d38e242a7e0b9e4234f11be6b5778432800a26d73ba72f39e6e81204b661b2b6b972e35445cdf2c052f02721467a9
7
+ data.tar.gz: a9b9b8813295aeb016f2cc051337d3fa80f369d4366a6bcbd61a4fa59a2f14c695f6a455c79764088fba046805fd2c4a237c11e2634846447e4143238d66d1eb
data/ext/z85/z85.c CHANGED
@@ -60,21 +60,18 @@ static byte decoder[96] = {
60
60
  0x21, 0x22, 0x23, 0x4F, 0x00, 0x50, 0x00, 0x00
61
61
  };
62
62
 
63
- static VALUE encode(VALUE _mod, VALUE string)
63
+ static VALUE Z85_encode(VALUE _mod, VALUE string)
64
64
  {
65
65
  byte* data = (byte*) StringValuePtr(string);
66
- long data_len = RSTRING_LEN(string);
66
+ long size = RSTRING_LEN(string);
67
67
 
68
- if (data_len % 4)
69
- rb_raise(rb_eRuntimeError, "Invalid string, number of bytes must be a multiple of 4");
70
-
71
- size_t encoded_len = data_len * 5 / 4;
68
+ size_t encoded_len = size * 5 / 4;
72
69
  char *encoded = malloc(encoded_len + 1);
73
70
  uint char_nbr = 0;
74
71
  uint byte_nbr = 0;
75
72
  uint32_t value = 0;
76
73
 
77
- while (byte_nbr < data_len) {
74
+ while (byte_nbr < size) {
78
75
  value = value * 256 + data[byte_nbr++];
79
76
  if (byte_nbr % 4 == 0) {
80
77
  uint divisor = 85 * 85 * 85 * 85;
@@ -89,36 +86,24 @@ static VALUE encode(VALUE _mod, VALUE string)
89
86
 
90
87
  VALUE out = rb_str_export_locale(rb_str_new_cstr(encoded));
91
88
  free(encoded);
92
-
93
89
  return out;
94
90
  }
95
91
 
96
- static VALUE _decode(VALUE string, int padding)
92
+ static VALUE Z85_decode(VALUE _mod, VALUE rstring)
97
93
  {
98
- char* data = StringValuePtr(string);
99
- long data_len = RSTRING_LEN(string) - padding;
100
-
101
- if (data_len % 5)
102
- rb_raise(rb_eRuntimeError, "Invalid string, number of bytes must be a multiple of 5");
103
-
104
- size_t decoded_size = data_len * 4 / 5;
105
-
106
- /* Verify the counter looks legit before even allocating memory. */
107
- if (padding) {
108
- int counter = data[data_len] - '0';
109
- if (counter < 0 || counter > 3)
110
- rb_raise(rb_eRuntimeError, "Invalid padding length");
111
- else if (decoded_size < (size_t) counter)
112
- rb_raise(rb_eRuntimeError, "Invalid padded string");
113
- }
94
+ char* string = StringValuePtr(rstring);
95
+ long strlen = RSTRING_LEN(rstring);
96
+ if (strlen % 5)
97
+ strlen--; /* It is padded, ignore the counter */
114
98
 
99
+ size_t decoded_size = strlen * 4 / 5;
115
100
  byte* decoded = malloc(decoded_size);
116
101
 
117
102
  uint byte_nbr = 0;
118
103
  uint char_nbr = 0;
119
104
  uint32_t value = 0;
120
- while (char_nbr < data_len) {
121
- value = value * 85 + decoder[(byte) data[char_nbr++] - 32];
105
+ while (char_nbr < strlen) {
106
+ value = value * 85 + decoder[(byte) string[char_nbr++] - 32];
122
107
  if (char_nbr % 5 == 0) {
123
108
  uint divisor = 256 * 256 * 256;
124
109
  while (divisor) {
@@ -129,32 +114,16 @@ static VALUE _decode(VALUE string, int padding)
129
114
  }
130
115
  }
131
116
 
132
- VALUE out = padding ?
133
- rb_str_new((const char*) decoded, decoded_size - (data[data_len] - '0')) :
134
- rb_str_new((const char*) decoded, decoded_size);
135
-
117
+ VALUE out = rb_str_new((const char*) decoded, decoded_size);
136
118
  free(decoded);
137
-
138
119
  return out;
139
120
  }
140
121
 
141
- static VALUE decode(VALUE _mod, VALUE string)
142
- {
143
- return _decode(string, 0);
144
- }
145
-
146
- static VALUE decode_with_padding(VALUE _mod, VALUE string)
147
- {
148
- return _decode(string, 1);
149
- }
150
-
151
122
  /* This function has a special name and it is invoked by Ruby to initialize the extension. */
152
123
  void Init_z85()
153
124
  {
154
125
  VALUE z85 = rb_define_module("Z85");
155
126
 
156
- rb_define_singleton_method(z85, "encode", encode, 1);
157
- rb_define_singleton_method(z85, "decode", decode, 1);
158
-
159
- rb_define_singleton_method(z85, "decode_with_padding", decode_with_padding, 1);
127
+ rb_define_singleton_method(z85, "_encode", Z85_encode, 1);
128
+ rb_define_singleton_method(z85, "_decode", Z85_decode, 1);
160
129
  }
data/lib/z85/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Z85
4
- VERSION = "0.5"
4
+ VERSION = "0.6"
5
5
  end
data/lib/z85.rb CHANGED
@@ -4,10 +4,46 @@ require "z85/z85"
4
4
  require "z85/version"
5
5
 
6
6
  module Z85
7
- def self.encode_with_padding(string)
8
- counter = 4 - (string.bytesize % 4)
9
- counter = 0 if counter == 4
10
- string += "\0" * counter if counter != 0
11
- encode(string) + counter.to_s
7
+ PADDINGS = ["", "\0", "\0\0", "\0\0\0"].freeze
8
+ private_constant :PADDINGS
9
+
10
+ class Error < StandardError; end
11
+
12
+ class << self
13
+ private def err(message)
14
+ raise Error, message
15
+ end
16
+
17
+ def encode(string)
18
+ if string.bytesize % 4 != 0
19
+ err "Input length should be 0 mod 4. Please, check Z85.encode_with_padding."
20
+ end
21
+ _encode(string)
22
+ end
23
+
24
+ def encode_with_padding(string)
25
+ counter = 4 - (string.bytesize % 4)
26
+ counter == 4 ? _encode(string) + "0" : _encode(string + PADDINGS[counter]) + counter.to_s
27
+ end
28
+
29
+ def decode(string)
30
+ if string.bytesize % 5 != 0
31
+ err "Input length should be 0 mod 5. Please, check Z85.decode_with_padding."
32
+ end
33
+ _decode(string)
34
+ end
35
+
36
+ def decode_with_padding(string)
37
+ err "Input length should be 1 mod 5" if string.bytesize % 5 != 1
38
+
39
+ counter = string[-1]
40
+ err "Invalid counter: #{counter}" if counter < "0" || counter > "3"
41
+
42
+ decoded = _decode(string)
43
+ size = decoded.bytesize - counter.to_i
44
+ err "String too short for counter #{counter}" if size < 0
45
+
46
+ decoded.slice!(0, size)
47
+ end
12
48
  end
13
49
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: z85
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.5'
4
+ version: '0.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xavier Noria