0

我正在尝试将 md5 字符串(base 16)转换为 c++ 中的 base 62 字符串。到目前为止,我发现的每个转换为 base 62 的解决方案只有在您可以将您的数字表示为 64 位整数或更小的整数时才有效。一个 md5 字符串是 128 位的,我一个人对此一无所获。

我应该只包含一个 bigint 库并完成它吗?

4

3 回答 3

4

让我们来看看。128/log2(62)=21.497。这意味着您需要 22 个“数字”来表示 base-62。

如果您只对不超过 22 个字符且不使用超过 62 个不同字符的字符串表示感兴趣,则不需要真正的 base-62 表示。您可以将 128 位分解为更小的部分并分别编码。这样您就不需要任何 128 位算术。您可以将 128 位拆分为 2x64 位,并使用长度为 11 的字符串对每个 64 位块进行编码。这样做甚至可以仅使用 57 个不同的字符。因此,您可以消除 62 个字符中的 5 个以避免任何“视觉歧义”。例如,删除 l,1,B,8。剩下 58 个不同的字符和 11*log2(58)=64.438 刚好够编码 64 位。

获得两个 64 位块并不难:

#include <climits>

#if CHAR_BIT != 8
#error "platform not supported, CHAR_BIT==8 expected"
#endif

// 'long long' is not yet part of C++
// But it's usually a supported extension
typedef unsigned long long uint64;

uint64 bits2uint64_bigendian(unsigned char const buff[]) {
   return (static_cast<uint64>(buff[0]) << 56)
        | (static_cast<uint64>(buff[1]) << 48)
        | (static_cast<uint64>(buff[2]) << 40)
        | (static_cast<uint64>(buff[3]) << 32)
        | (static_cast<uint64>(buff[4]) << 24)
        | (static_cast<uint64>(buff[5]) << 16)
        | (static_cast<uint64>(buff[6]) <<  8)
        |  static_cast<uint64>(buff[7]);
}

int main() {
   unsigned char md5sum[16] = {...};
   uint64 hi = bits2uint64_bigendian(md5sum);
   uint64 lo = bits2uint64_bigendian(md5sum+8);
}
于 2010-10-24T07:26:09.023 回答
4

为简单起见,您可以使用我的 uint128_t c++ 类 ( http://www.codef00.com/code/uint128.h )。有了它,基本转换器看起来就像这样简单:

#include "uint128.h"
#include <iostream>
#include <algorithm>

int main() {
    char a[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    uint128_t x = U128_C(0x130eb6003540debd012d96ce69453aed);

    std::string r;
    r.reserve(22); // shouldn't result in more than 22 chars 
                   // 6-bits per 62-bit value means (128 / 6 == 21.3)

    while(x != 0) {
        r += a[(x % 62).to_integer()];
        x /= 62;
    }

    // when converting bases by division, the digits are reversed...fix that :-)
    std::reverse(r.begin(), r.end());
    std::cout << r << std::endl;
}

这打印:

J7JWEJ0YbMGqaJFCGkUxZ
于 2010-10-24T07:08:10.080 回答
0

GMP为任意精度整数提供了方便的 c++ 绑定

于 2010-10-24T06:36:13.503 回答