luikore
2013-06-14 06:51:48 +08:00
源字符串里, 可打印字符的码点不超过 127, 故每 2 个字节可以对应成1个unsigned short, 而且不超过 127*256 = 32512
目标字符串里, 8 个不同的字符有 8! = 40320 种排列 > 32512
所以每 2 字节映射到一个无符号 16 位整数, 然后作为下标在预先计算好的, 大小为 40320 的全排列表中查找就可以了
ruby 代码 (to 看不懂的: unpack 就和 php/perl/python 的 unpack 差不多, each 和 each_with_index 相当于 for 循环, to_a 是把range/迭代器转换成数组)
---
CHARS64 = [*'a'..'z', *'A'..'Z', *'0'..'9', '+', '=']
PTABLE = (0..7).to_a.permutation.to_a
s = "hello world" # 源字符串
s_len16 = s.ljust 16, "\0" # 给不足 16 字节的部分补上 nul
r = '' # 目标字符串
s_len16.unpack('S*').each_with_index do |c16, i|
PTABLE[c16].each{|e| r << CHARS64[e + i * 8] }
end
print(r) #=> fbadghcenlmjoikprvuqxwtsDCBEFAzyLJKHNGIMOPQVRUSTWXYZ0123456789+=