将代码从5位转换为3位字符

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将代码从5位转换为3位字符相关的知识,希望对你有一定的参考价值。

我有一个由五位小数组成的代码,我需要将它存储(压缩)在一个只能包含3个字母数字ascii可打印字符的字段中。是否可以在两个字段之间进行双向转换?怎么用C?

答案

要使用三位数表示0到99999之间的任何数字,您需要将数字从基数10转换为更高的基数b,其中b3> 99999。

满足此要求的最小基数为47.有97个可打印的ASCII字符可供选择,所以显然没有问题。

顺便提一下,如果您要将数字转换为用户可见的字符串,您可能需要考虑选择不会形成bum等不幸字符串的字符。

以下代码应该有效。它没有经过优化,但应该足够快,除非您需要每秒转换数百万个数字。

#define ALPHABET "26789BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz"
#define LEN_ALPH 47

unsigned int asc2int(char *s) {
    unsigned int i, result = 0;
    while (*s) {
        for (i=0; i<LEN_ALPH; i++) {
            if (*s == ALPHABET[i]) break;
        }
        if (i == LEN_ALPH) return 0; /* Illegal character in input */
        result = result * LEN_ALPH + i;  /* TODO: Check for overflow */
        s++;
    }
    return result;
}

char *int2asc(unsigned int n) {
    static char result[7];  /* Should be sufficient for any 32-bit input */
    char *ptr = result+6;
    *ptr = '';
    if (n == 0) {
        *(--ptr) = ALPHABET[0];
    }
    else {
        while (n) {
            *(--ptr) = ALPHABET[n % LEN_ALPH];
            n /= LEN_ALPH;
        }
    }
    return ptr;
}


int main() {
    unsigned int tests[10] = { 0, 1, 10, 100, 1000, 10000, 11111, 12345, 54321, 99999 };
    unsigned int i, n;
    char *s;

    /* Test with selected numbers */
    for (i=0; i<10; i++) {
        s = int2asc(tests[i]);
        n = asc2int(s);
        printf("%u -> %s -> %u
", tests[i], s, n);
    }

    /* Test all numbers */
    for (i=0; i<100000; i++) {
        if (asc2int(int2asc(i)) != i) {
            printf("Failed at i=%u
", i);
            return 1;
        }
    }
    return 0;
}
另一答案

除非您愿意使用大写和小写字母以及数字,否则这是不可能的。

有90,000个这样的代码,正好有5个小数,并且被舍入的立方根是45.所以单个字母数字字符必须有45种可能性。

因此,在您的情况下,请考虑使用Base64编码,它本身已成为标准:https://en.wikipedia.org/wiki/Base64

以上是关于将代码从5位转换为3位字符的主要内容,如果未能解决你的问题,请参考以下文章

Java:将位字符串转换为字节[]

将内存中的 16 位转换为 std::string

C语言如何将64位整数转字符串

如何将 3 位 HTML 十六进制颜色转换为 6 位 flex 十六进制颜色

vba怎么存储17位数字

转换为 3 位十六进制颜色代码