不懂就问:UUID的压缩算法是怎么样的呢?

预制体里面绑定的脚本是使用压缩后的uuid ,请问这个压缩uuid算法在哪儿可以查看到?
image
image

请问樱木兄,预制里的这个uuid,跟引用脚本本身的uuid不一样吗,是压缩过的吗?

是的,场景和预制体里面的脚本引用的是压缩后的uuid

如果不涉及机密的话,想请问一下你们现在是要做什么功能,需要搞懂这个uuid压缩算法呢?

base64转base16 以下是java代码

public static String toBase16(String base64) {
// 64个字符集
String base64Chars = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”;

    int decimalValue = 0;
    // 将每个字符转成相应的64进制数值,并计算十进制总值
    for (int i = 0; i < base64.length(); i++) {
        char c = base64.charAt(i);
        int charValue = base64Chars.indexOf(c);

        decimalValue = decimalValue * 64 + charValue;
    }

    // 转换为16进制
    String base16 = Integer.toHexString(decimalValue).toLowerCase();
    return String.format("%3s", base16).replace(' ', '0');
}

要将项目内文件的uuid都重新生成,然后在把老的uuid全局查找替换成新的uuid ,发现脚本的引用使用的是压缩后的uuid ,导致会替换不到,丢引用了

var Base64KeyChars = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”;

var AsciiTo64 = new Array(128);

for (var i = 0; i < 128; ++i) { AsciiTo64[i] = 0; }

for (i = 0; i < 64; ++i) { AsciiTo64[Base64KeyChars.charCodeAt(i)] = i; }

var Reg_Dash = /-/g;

var Reg_Uuid = /^[0-9a-fA-F-]{36}$/;

var Reg_NormalizedUuid = /^[0-9a-fA-F]{32}$/;

var Reg_CompressedUuid = /^[0-9a-zA-Z+/]{22,23}$/;

export var UuidUtils = {

// 加了这个标记后,字符串就不可能会是 uuid 了。

NonUuidMark: '.',

// 压缩后的 uuid 可以减小保存时的尺寸,但不能做为文件名(因为无法区分大小写并且包含非法字符)。

// 默认将 uuid 的后面 27 位压缩成 18 位,前 5 位保留下来,方便调试。

// fc991dd7-0033-4b80-9d41-c8a86a702e59 -> fc9913XADNLgJ1ByKhqcC5Z

// 如果启用 min 则将 uuid 的后面 30 位压缩成 20 位,前 2 位保留不变。

// fc991dd7-0033-4b80-9d41-c8a86a702e59 -> fcmR3XADNLgJ1ByKhqcC5Z

/*

 * @param {Boolean} [min=false]

 */

compressUuid: function (uuid, min) {

    if (Reg_Uuid.test(uuid)) {

        uuid = uuid.replace(Reg_Dash, '');

    }

    else if (!Reg_NormalizedUuid.test(uuid)) {

        return uuid;

    }

    var reserved = (min === true) ? 2 : 5;

    return UuidUtils.compressHex(uuid, reserved);

},

compressHex: function (hexString, reservedHeadLength) {

    var length = hexString.length;

    var i;

    if (typeof reservedHeadLength !== 'undefined') {

        i = reservedHeadLength;

    }

    else {

        i = length % 3;

    }

    var head = hexString.slice(0, i);

    var base64Chars = [];

    while (i < length) {

        var hexVal1 = parseInt(hexString[i], 16);

        var hexVal2 = parseInt(hexString[i + 1], 16);

        var hexVal3 = parseInt(hexString[i + 2], 16);

        base64Chars.push(Base64KeyChars[(hexVal1 << 2) | (hexVal2 >> 2)]);

        base64Chars.push(Base64KeyChars[((hexVal2 & 3) << 4) | hexVal3]);

        i += 3;

    }

    return head + base64Chars.join('');

},

decompressUuid: function (str) {

    if (str.length === 23) {

        // decode base64

        var hexChars = [];

        for (var i = 5; i < 23; i += 2) {

            var lhs = AsciiTo64[str.charCodeAt(i)];

            var rhs = AsciiTo64[str.charCodeAt(i + 1)];

            hexChars.push((lhs >> 2).toString(16));

            hexChars.push((((lhs & 3) << 2) | rhs >> 4).toString(16));

            hexChars.push((rhs & 0xF).toString(16));

        }

        //

        str = str.slice(0, 5) + hexChars.join('');

    }

    else if (str.length === 22) {

        // decode base64

        var hexChars = [];

        for (var i = 2; i < 22; i += 2) {

            var lhs = AsciiTo64[str.charCodeAt(i)];

            var rhs = AsciiTo64[str.charCodeAt(i + 1)];

            hexChars.push((lhs >> 2).toString(16));

            hexChars.push((((lhs & 3) << 2) | rhs >> 4).toString(16));

            hexChars.push((rhs & 0xF).toString(16));

        }

        //

        str = str.slice(0, 2) + hexChars.join('');

    } else {

        return str;

    }

    return [str.slice(0, 8), str.slice(8, 12), str.slice(12, 16), str.slice(16, 20), str.slice(20)].join('-');

},

isUuid: function (str) {

    return Reg_CompressedUuid.test(str) || Reg_NormalizedUuid.test(str) || Reg_Uuid.test(str);

}

};

膜拜大佬,不过好奇大佬是怎么一眼看出是base64转base16的呢?

做逆向研究的

厉害了樱木兄 :+1:

多谢大佬,我试试看

多谢大佬,我试试看下