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.
- checksums.yaml +4 -4
- data/ext/z85/z85.c +15 -46
- data/lib/z85/version.rb +1 -1
- data/lib/z85.rb +41 -5
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebd3df9b05fe5482e386d7940d6ba1c08c6d24d46aa01a65894ca7911f4d94f9
|
4
|
+
data.tar.gz: 40edd0c27fbc90cec3f897bfff9b6ee07ce83435046c87b41074f363d5534e52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
63
|
+
static VALUE Z85_encode(VALUE _mod, VALUE string)
|
64
64
|
{
|
65
65
|
byte* data = (byte*) StringValuePtr(string);
|
66
|
-
long
|
66
|
+
long size = RSTRING_LEN(string);
|
67
67
|
|
68
|
-
|
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 <
|
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
|
92
|
+
static VALUE Z85_decode(VALUE _mod, VALUE rstring)
|
97
93
|
{
|
98
|
-
char*
|
99
|
-
long
|
100
|
-
|
101
|
-
|
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 <
|
121
|
-
value = value * 85 + decoder[(byte)
|
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 =
|
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, "
|
157
|
-
rb_define_singleton_method(z85, "
|
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
data/lib/z85.rb
CHANGED
@@ -4,10 +4,46 @@ require "z85/z85"
|
|
4
4
|
require "z85/version"
|
5
5
|
|
6
6
|
module Z85
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|