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