10进制数的压缩

0.应用场景

笔者最近遇到了一个需求:需要将一个19位的十进制数映射为一个小于等于10位的编码。为了确保代码的优雅性和实现一对一的映射关系,笔者决定采用进制转换的思路来解决这个问题。

1.进制确定

先加假设进制数为X,为了确保1对1的关系,我们需要确定的就是19位的十进制数能表示的所有19位数字的数量,也就是 ( 1 0 19 − 1 ) − 1 0 18 (10^{19} - 1)-10^{18} 101911018(最大19位数-最小19位数); 要小于10位X进制所能表示的最大数 X 10 − 1 X^{10} - 1 X101(X进制最大10位数),
即: ( 1 0 19 − 1 ) − 1 0 18 < X 10 − 1 (10^{19} - 1)-10^{18} < X^{10} - 1 101911018<X101

9 ⋅ 1 0 18 < X 10 9 \cdot 10^{18} < X^{10} 91018<X10

9 ⋅ 1 0 18 10 < X \sqrt[10]{9 \cdot 10^{18}} < X 1091018 <X

result = (9 * 10**18) ** (1/10)
print(result)

在这里插入图片描述
因此X最小取79进制。
接下来,我们需要确定如何表示 X 进制 的每一位。笔者首先考虑使用 ASCII 字符表,但发现其中包含一些不可打印的字符(如控制字符和空格),这会导致编码结果难以阅读和处理。因此,最终决定选取 93 个可见字符 作为 93 进制的符号集。(如下表)

ascii_printable = {
    0: '!', 1: '"', 2: '#', 3: '$', 4: '%', 5: '&', 6: "'", 7: '(', 8: ')', 9: '*',
    10: '+', 11: ',', 12: '-', 13: '.', 14: '/', 15: '0', 16: '1', 17: '2', 18: '3', 19: '4',
    20: '5', 21: '6', 22: '7', 23: '8', 24: '9', 25: ':', 26: ';', 27: '<', 28: '=', 29: '>',
    30: '?', 31: '@', 32: 'A', 33: 'B', 34: 'C', 35: 'D', 36: 'E', 37: 'F', 38: 'G', 39: 'H',
    40: 'I', 41: 'J', 42: 'K', 43: 'L', 44: 'M', 45: 'N', 46: 'O', 47: 'P', 48: 'Q', 49: 'R',
    50: 'S', 51: 'T', 52: 'U', 53: 'V', 54: 'W', 55: 'X', 56: 'Y', 57: 'Z', 58: '[', 59: '\\',
    60: ']', 61: '^', 62: '_', 63: '`', 64: 'a', 65: 'b', 66: 'c', 67: 'd', 68: 'e', 69: 'f',
    70: 'g', 71: 'h', 72: 'i', 73: 'j', 74: 'k', 75: 'l', 76: 'm', 77: 'n', 78: 'o', 79: 'p',
    80: 'q', 81: 'r', 82: 's', 83: 't', 84: 'u', 85: 'v', 86: 'w', 87: 'x', 88: 'y', 89: 'z',
    90: '{', 91: '|', 92: '}', 93: '~'
}

2.代码示例

# 定义可打印的 93 个字符(去掉空格和删除字符)
ascii_printable = [chr(i) for i in range(33, 127) if i != 127]

# 创建字符到值的映射字典
ascii_to_value = {char: idx for idx, char in enumerate(ascii_printable)}

# 将 10 进制数转换为 93 进制
def decimal_to_base93(n):
    if n == 0:
        return [0]
    digits = []
    while n > 0:
        digits.append(n % 93)
        n = n // 93
    return digits[::-1]  # 反转列表以得到正确的顺序

# 将 93 进制的每一位映射到 ASCII 字符
def base93_to_ascii(base93_digits):
    return ''.join(ascii_printable[digit] for digit in base93_digits)

# 将 ASCII 字符串转换回 93 进制
def ascii_to_base93(ascii_str):
    return [ascii_to_value[char] for char in ascii_str]

# 将 93 进制数转换回 10 进制数
def base93_to_decimal(base93_digits):
    n = 0
    for digit in base93_digits:
        n = n * 93 + digit
    return n

# 示例:将一个 19 位的 10 进制数转换为 93 进制的 10 位 ASCII 字符串
n = 1234567890123456789  # 替换为你的 19 位数字
base93_digits = decimal_to_base93(n)
ascii_result = base93_to_ascii(base93_digits)

print("93 进制表示:", base93_digits)
print("ASCII 表示:", ascii_result)

# 将 ASCII 字符串转换回 10 进制数
decoded_base93 = ascii_to_base93(ascii_result)
decoded_n = base93_to_decimal(decoded_base93)

print("解码后的 93 进制表示:", decoded_base93)
print("解码后的 10 进制数:", decoded_n)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值