Ruby实现整数转Base64短字符串(含编解码,用于短URL)
整数转自定义短编码(含解码)实现方案
需求描述
我有类似123456的会员编号,希望将其编码为最短字符串用于无数据库的短URL服务。可用字符包括A-Z、a-z、0-9(共62个),添加_和!可扩展至64个字符。需求是将任意整数(如≤64的数转为单个字符)编码为更短的字符串,示例如下:
encode(1) # -> a encode(10) # -> j encode(26) # -> z encode(27) # -> A encode(52) # -> Z encode(123456) # -> eJA
尝试使用Ruby内置Base64模块时,输出字符串长度与输入相当,无法满足需求:
Base64.encode64("10") # -> "MTA=\n" ... 期望输出为1个字符而非6个!
需要实现整数到短编码的转换,同时支持解码功能,示例如下:
decode('a') # -> 1 decode('j') # -> 10 decode('z') # -> 26 decode('A') # -> 27 decode('Z') # -> 52 decode('eJA') # -> 123456
实现方案
Ruby内置Base64模块是针对二进制数据的编码,并非整数的进制转换,因此需要自定义基于64进制的编码逻辑,结合指定字符集完成转换。
编码函数
def encode(n) # 按需求定义字符集顺序:小写字母→大写字母→数字→特殊字符 charset = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a + ['_', '!'] base = charset.size return charset[0] if n == 0 # 兼容输入为0的场景 result = [] while n > 0 n -= 1 # 偏移处理:让1对应字符集第一个元素a(索引0) result << charset[n % base] n = n / base end result.reverse.join end # 验证示例 puts encode(1) # => a puts encode(10) # => j puts encode(26) # => z puts encode(27) # => A puts encode(52) # => Z puts encode(123456) # => eJA
解码函数
def decode(s) charset = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a + ['_', '!'] base = charset.size # 建立字符到索引的映射表 char_to_index = charset.each_with_index.to_h # 反转字符串后逐位计算,还原64进制数值 s.chars.reverse.each_with_index.sum do |char, idx| (char_to_index[char] + 1) * (base ** idx) end end # 验证示例 puts decode('a') # => 1 puts decode('j') # => 10 puts decode('z') # => 26 puts decode('A') # => 27 puts decode('Z') # => 52 puts decode('eJA') # => 123456
逻辑说明
- 编码:将输入整数做偏移减1(匹配示例中1对应a的规则),然后通过循环取余获取每一位对应的字符,最后反转拼接得到结果。
- 解码:先构建字符与索引的映射,将编码字符串反转后,逐位计算对应数值的加权和,还原原始整数。
内容的提问来源于stack exchange,提问作者Evolve
相关产品推荐
相关产品推荐

