сделать UUID (rfc4122) какое пространство имен для хэширования полного содержимого? - PullRequest
2 голосов
/ 24 июня 2011

Я учусь писать программное обеспечение для блогов, поэтому я прочитал об Atom, который требует уникальный идентификатор. Похоже, то, что вы должны сделать, это urn: uuid: type IRI.

Для меня имеет смысл получить глобально уникальный идентификатор для хеширования содержимого поста.

Я написал код (см. Ниже) для генерации UUID, совместимого с rfc-4122 (версия 5), за исключением того, что я не уверен, что вставлять в пространство имен.

RFC говорит, что не может сказать, какое пространство имен мне следует использовать, и приводит несколько примеров, ни один из которых не кажется правильным. Я немного погуглил и не увидел никаких рекомендаций, кроме тех, которые содержатся в RFC.

Пространство имен само по себе должно быть UUID, поэтому я не должен просто вставлять что-то вроде "хеша всего поста" в качестве пространства имен.

Чтобы сгенерировать [все, кроме 6 бит] UUID версии 5, вы объединяете UUID пространства имен (в необработанном виде) со своим «именем».

Итак ... вот мой вопрос: существует ли UUID пространства имен для использования всего содержимого вашего документа в качестве «имени»?

Или я должен сделать случайный (v4) UUID и использовать его в качестве своего личного пространства имен «весь пост»?

Или что-то еще?

Спасибо, - Джейсон

P.S. Я написал генератор UUID для узла, который сейчас использует пространство имен ns: URL. Вот код, если вы заинтересованы:

// Copyright 2011 Jason Woofenden -- CC0
//
// An almost correct rfc-4122 v5 UUID generator for node (see http://node.js)
//
// To test, run this with node, then compare the out put of these:
//
//   curl http://localhost:8129/foo
//   uuid -v 5 ns:URL foo
//
// Replace "foo" with any string and they should still be the same.

var
    http = require('http'),
    crypto = require('crypto'),
    url = require('url');
    hex_high_10 = { // set the highest bit and clear the next highest
        '0': '8',
        '1': '9',
        '2': 'a',
        '3': 'b',
        '4': '8',
        '5': '9',
        '6': 'a',
        '7': 'b',
        '8': '8',
        '9': '9',
        'a': 'a',
        'b': 'b',
        'c': '8',
        'd': '9',
        'e': 'a',
        'f': 'b'
    }

http.createServer(function (req, res) {
    var sum = crypto.createHash('sha1');

    // namespace in raw form. FIXME using ns:URL for now, what should it be?
    sum.update(new Buffer('a6e4EZ2tEdGAtADAT9QwyA==', 'base64'));

    // add HTTP path
    sum.update(url.parse(req.url).pathname.substr(1));

    // get sha1 hash in hex form
    var uuid = sum.digest('hex');

    // format as UUID (add dashes, version bits and reserved bits)
    uuid =
        uuid.substr(0, 8) + '-' + // time_low
        uuid.substr(8, 4) + '-' + // time_mid
        '5' + // time_hi_and_version high 4 bits (version)
        uuid.substr(13, 3) + '-' + // time_hi_and_version low 4 bits (time high)
        hex_high_10[uuid.substr(16, 1)] + uuid.substr(17, 1) + // cloc_seq_hi_and_reserved
        uuid.substr(18, 2) + '-' + // clock_seq_low
        uuid.substr(20, 12); // node

    // spit it out
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(uuid + '\n');
}).listen(8129, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8129/');

Ответы [ 3 ]

2 голосов
/ 24 июня 2011

Некоторое время назад я столкнулся с тем же вопросом и пришел к выводу, что использование UUID v4 для пространства имен является правильным решением. По сути, я хотел сгенерировать UUID из строки, и вот что я делаю (на Java, но достаточно просто для перевода на JS):

public final class FooIdGen {

    /**
     * The namespace id for generating Foo - UUIDs from the foo - id
     * strings.
     */
    public final static String NAMESPACE =
            "0416141a-5229-4d16-94cc-43d546ef1118"; //NOI18N

    private final static byte[] NS_BYTES =
            uuidToBytes(UUID.fromString(NAMESPACE));

    /**
     * Generates a UUID for a given foo - id.
     *
     * @param fooId the reporter ID to get the UUID for
     * @return the UUID for the specified foo ID
     */
    public static UUID uuidForFooId(String fooId) {
        final byte[] idBytes;

        try {
            idBytes = fooId.getBytes("US-ASCII"); //NOI18N
        } catch (UnsupportedEncodingException ex) {
            /* pretty sure US-ASCII is ok, so this can't happen */
            throw new AssertionError(ex.toString());
        }

        final byte[] tmp = Arrays.copyOf(
                NS_BYTES, idBytes.length + NS_BYTES.length);

        System.arraycopy(idBytes, 0, tmp, NS_BYTES.length, idBytes.length);

        return UUID.nameUUIDFromBytes(tmp);
    }

    /* want it to align, so that's ok */
    @SuppressWarnings("PointlessBitwiseExpression")
    private static byte[] uuidToBytes(UUID id) {
        final long h = id.getMostSignificantBits();
        final long l = id.getLeastSignificantBits();
        final byte[] result = new byte[16];

        int i=0;
        result[i++] = (byte) ((h >> 56) & 0xff);
        result[i++] = (byte) ((h >> 48) & 0xff);
        result[i++] = (byte) ((h >> 40) & 0xff);
        result[i++] = (byte) ((h >> 32) & 0xff);
        result[i++] = (byte) ((h >> 24) & 0xff);
        result[i++] = (byte) ((h >> 16) & 0xff);
        result[i++] = (byte) ((h >>  8) & 0xff);
        result[i++] = (byte) ((h >>  0) & 0xff);

        result[i++] = (byte) ((l >> 56) & 0xff);
        result[i++] = (byte) ((l >> 48) & 0xff);
        result[i++] = (byte) ((l >> 40) & 0xff);
        result[i++] = (byte) ((l >> 32) & 0xff);
        result[i++] = (byte) ((l >> 24) & 0xff);
        result[i++] = (byte) ((l >> 16) & 0xff);
        result[i++] = (byte) ((l >>  8) & 0xff);
        result[i++] = (byte) ((l >>  0) & 0xff);

        return result;
    }

    private FooIdGen() {
        /* no instances */
    }
}
1 голос
/ 20 сентября 2014

Вот некоторый код CoffeeScript, который я использую для генерации UUID v4 с использованием хэша Sha-1 чего-либо.(Конвертировать в Javascript используя http://js2coffee.org.)

# Compute a uuid v4 from the Sha-1 hash of data.
crypto = require('crypto')
exports.uuidsha1 = (data) ->
    sha1sum = crypto.createHash('sha1')
    sha1sum.update(data)
    s = sha1sum.digest('hex')
    i = -1
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) ->
        i += 1
        switch c
            when 'x'
                return s[i]
            when 'y'
                # take 8 + low order 3 bits of hex number.
                return ((parseInt('0x'+s[i],16)&0x3)|0x8).toString(16)
    )
0 голосов
/ 25 июня 2011

Возможно, вы захотите проверить node-uuid.Я еще не использую его, но планирую рассмотреть его поближе, когда мне понадобится функция такого типа.Это может не соответствовать вашим потребностям, но я подумал, что вы должны знать об этом.https://github.com/broofa/node-uuid

...