2

オブジェクト識別子からいくつかのバイナリ データ ファイルを作成する必要があります。これは、最大 64 バイトの可変長バイナリ void* バッファであり、印刷できない文字に対応する任意のバイトも含めることができます。印刷できない文字が含まれているため、オブジェクト識別子をファイル名として使用できません。一意のファイル名を作成するための提案。この場合、UUID をどのように導出または使用できますか?

4

1 に答える 1

4

バイトを 16 進文字列に変換できます。

#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 に答える