2

我需要从对象标识符创建一些二进制数据文件,这是一个可变长度的二进制 void* 缓冲区,最多 64 个字节,并且还可以包含与不可打印字符对应的任何字节。我不能使用对象标识符作为我的文件名,因为它包含不可打印的字母。创建唯一文件名的任何建议。在这种情况下如何派生或使用 UUID?

4

1 回答 1

4

您可以将字节转换为十六进制字符串。

#define tohex(x) ("0123456789abcdef"[(x) & 0x0f])
char buf[129];
assert(objid_len <= 64);
for (int i = 0; i < objid_len; ++i) {
    buf[2*i] = tohex(objid[i] >> 4);
    buf[2*i+1] = tohex(objid[i]);
}
buf[2*objid_len] = '\0';

您可以通过使用在用于表示对象 ID 的字母表之外的填充字符来使文件名具有通用长度。如果需要更短的文件名,则可以使用更高的基数。例如,Base64

const char * const base64str =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#define tob64(x) base64str[(x) & 0x3f]

void objid_to_filename (const unsigned char *objid, int objid_len,
                        char *buf) {
    memset(buf, '-', 88);
    buf[88] = '\0';
    int i = 0, j = 0;
    int buflen = 4 * ((objid_len + 2)/3);
    while (i < objid_len) {
        unsigned x = 0;
        x |= (i < objid_len) ? objid[i++] << 16 : 0;
        x |= (i < objid_len) ? objid[i++] <<  8 : 0;
        x |= (i < objid_len) ? objid[i++] <<  0 : 0;
        buf[j++] = tob64(x >> 18);
        buf[j++] = tob64(x >> 12);
        buf[j++] = tob64(x >>  6);
        buf[j++] = tob64(x >>  0);
    }
    int pad = (3 - (objid_len % 3)) % 3;
    for (i = 0; i < pad; ++i) buf[buflen - 1 - i] = '=';
}
于 2013-06-27T00:40:45.357 回答