id_shuffler 0.0.1 → 0.0.2
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.
- data/ext/id_shuffler/id_shuffler.c +25 -21
- data/lib/id_shuffler.rb +10 -6
- metadata +1 -1
@@ -15,25 +15,27 @@ static VALUE r_base32_shuffle(VALUE self, VALUE original_num, VALUE key_str) {
|
|
15
15
|
// initialize the feistel network and lfsr
|
16
16
|
unsigned int keypos, key_len;
|
17
17
|
unsigned long l, r, r_orig;
|
18
|
-
unsigned long
|
18
|
+
unsigned long lfsr, lfsr_check_bit, lfsr_out_bit, lfsr_round;
|
19
19
|
l = (original >> 15) & 32767;
|
20
20
|
r = original & 32767;
|
21
21
|
key_len = strlen(key);
|
22
22
|
// apply the feistel network in a loop over each char in key. the round
|
23
|
-
// function uses the key
|
24
|
-
// lfsr
|
23
|
+
// function uses the current key character as the taps mask for several
|
24
|
+
// iterations of a 32-bit lfsr
|
25
25
|
for (keypos = 0; keypos < key_len; keypos++) {
|
26
26
|
r_orig = r;
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
lfsr = r + 255; // ensure nonzero starting condition in the lfsr
|
28
|
+
for (lfsr_round = 0; lfsr_round < 15; lfsr_round++) {
|
29
|
+
lfsr_out_bit = 0;
|
30
|
+
for (lfsr_check_bit = 0; lfsr_check_bit < 8; lfsr_check_bit++) {
|
31
|
+
if ((key[keypos] & (1 << lfsr_check_bit)) > 0) {
|
32
|
+
lfsr_out_bit = lfsr_out_bit ^ ((lfsr & (1 << lfsr_check_bit)) >> lfsr_check_bit);
|
33
|
+
}
|
32
34
|
}
|
35
|
+
lfsr = (lfsr << 1) + lfsr_out_bit;
|
33
36
|
}
|
34
|
-
|
35
|
-
|
36
|
-
r = (l ^ lfsr_num);
|
37
|
+
lfsr = lfsr & 32767;
|
38
|
+
r = (l ^ lfsr);
|
37
39
|
l = r_orig;
|
38
40
|
}
|
39
41
|
// base32 encode the result
|
@@ -73,25 +75,27 @@ static VALUE r_base32_unshuffle(VALUE self, VALUE shuffled_str, VALUE key_str) {
|
|
73
75
|
return INT2NUM(-1);
|
74
76
|
}
|
75
77
|
}
|
76
|
-
//
|
78
|
+
// unwind
|
77
79
|
int keypos,key_len;
|
78
80
|
unsigned long l, r, l_orig;
|
79
|
-
unsigned long
|
81
|
+
unsigned long lfsr, lfsr_check_bit, lfsr_out_bit, lfsr_round;
|
80
82
|
l = (shuffled >> 15) & 32767;
|
81
83
|
r = shuffled & 32767;
|
82
84
|
key_len = strlen(key);
|
83
85
|
for (keypos = (key_len - 1); keypos >= 0; keypos--) {
|
84
86
|
l_orig = l;
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
87
|
+
lfsr = l + 255;
|
88
|
+
for (lfsr_round = 0; lfsr_round < 15; lfsr_round++) {
|
89
|
+
lfsr_out_bit = 0;
|
90
|
+
for (lfsr_check_bit = 0; lfsr_check_bit < 8; lfsr_check_bit++) {
|
91
|
+
if ((key[keypos] & (1 << lfsr_check_bit)) > 0) {
|
92
|
+
lfsr_out_bit = lfsr_out_bit ^ ((lfsr & (1 << lfsr_check_bit)) >> lfsr_check_bit);
|
93
|
+
}
|
90
94
|
}
|
95
|
+
lfsr = (lfsr << 1) + lfsr_out_bit;
|
91
96
|
}
|
92
|
-
|
93
|
-
|
94
|
-
l = (r ^ lfsr_num);
|
97
|
+
lfsr = lfsr & 32767;
|
98
|
+
l = (r ^ lfsr);
|
95
99
|
r = l_orig;
|
96
100
|
}
|
97
101
|
// return the resulting original number as a ruby fixnum
|
data/lib/id_shuffler.rb
CHANGED
@@ -17,6 +17,10 @@ class IdShuffler
|
|
17
17
|
@key = Digest::MD5.digest(key)
|
18
18
|
end
|
19
19
|
|
20
|
+
# note the c extension defines the two class methods:
|
21
|
+
# - shuffle_with_raw_key
|
22
|
+
# - unshuffle_with_raw_key
|
23
|
+
|
20
24
|
def shuffle(i)
|
21
25
|
self.class.shuffle_with_raw_key(i.to_i, @key)
|
22
26
|
end
|
@@ -25,16 +29,16 @@ class IdShuffler
|
|
25
29
|
self.class.unshuffle_with_raw_key(s.to_s, @key)
|
26
30
|
end
|
27
31
|
|
32
|
+
# these class methods are here for convenience but they are slower because the
|
33
|
+
# md5 is computed each time. better to use an instance with an initialized
|
34
|
+
# key.
|
35
|
+
|
28
36
|
def self.shuffle(i, key)
|
29
|
-
|
30
|
-
@keycache[key] ||= Digest::MD5.digest(key)
|
31
|
-
shuffle_with_raw_key(i.to_i, @keycache[key])
|
37
|
+
shuffle_with_raw_key(i.to_i, Digest::MD5.digest(key))
|
32
38
|
end
|
33
39
|
|
34
40
|
def self.unshuffle(s, key)
|
35
|
-
|
36
|
-
@keycache[key] ||= Digest::MD5.digest(key)
|
37
|
-
unshuffle_with_raw_key(s.to_s, @keycache[key])
|
41
|
+
unshuffle_with_raw_key(s.to_s, Digest::MD5.digest(key))
|
38
42
|
end
|
39
43
|
|
40
44
|
end
|