天天看點

UUID原理以及使用普通調用:淺析普通調用原理:

普通調用:

不用導包,直接寫了全路徑

public static String generatorUUIDAndReplace(Boolean replace){
        String uuid = java.util.UUID.randomUUID().toString();
        if(replace){
            uuid = uuid.replaceAll("-","");
        }
        return uuid;
    }
           

傳值true則去除-,傳值false保留-

淺析普通調用原理:

點到randomUUID()方法裡面可以看到

public static UUID randomUUID() {
        SecureRandom ng = Holder.numberGenerator;

        byte[] randomBytes = new byte[16];
        ng.nextBytes(randomBytes);
        randomBytes[6]  &= 0x0f;  /* clear version        */
        randomBytes[6]  |= 0x40;  /* set to version 4     */
        randomBytes[8]  &= 0x3f;  /* clear variant        */
        randomBytes[8]  |= 0x80;  /* set to IETF variant  */
        return new UUID(randomBytes);
    }
           

打個斷點檢視一下流程

UUID原理以及使用普通調用:淺析普通調用原理:

可以看出

SecureRandom ng = Holder.numberGenerator;
        byte[] randomBytes = new byte[16];
           

這兩句代碼是建立一個16位的byte數組,後續代碼指派。

UUID原理以及使用普通調用:淺析普通調用原理:

說明了

這句代碼是給byte數組指派的。

UUID原理以及使用普通調用:淺析普通調用原理:

這裡隻是将byte數組設定為版本4,并設定為IETF變體;

點開UUID的有參構造

private UUID(byte[] data) {
        long msb = 0;
        long lsb = 0;
        assert data.length == 16 : "data must be 16 bytes in length";
        for (int i=0; i<8; i++)
            msb = (msb << 8) | (data[i] & 0xff);
        for (int i=8; i<16; i++)
            lsb = (lsb << 8) | (data[i] & 0xff);
        this.mostSigBits = msb;
        this.leastSigBits = lsb;
    }
           

使用位元組數組構造新UUID的私有構造函數。這裡有兩個屬性值mostSigBits和leastSigBits在toString()方法裡面有調用。點進去可以看到

public String toString() {
        return (digits(mostSigBits >> 32, 8) + "-" +
                digits(mostSigBits >> 16, 4) + "-" +
                digits(mostSigBits, 4) + "-" +
                digits(leastSigBits >> 48, 4) + "-" +
                digits(leastSigBits, 12));
    }
           

将uuid對象轉換成uuid格式的字元串,點進digits方法裡面

private static String digits(long val, int digits) {
        long hi = 1L << (digits * 4);
        return Long.toHexString(hi | (val & (hi - 1))).substring(1);
    }
           

digits方法的作用是傳回由指定數量的十六進制數字表示的val。toHexString将Long類型轉換成字元串類型,substring是切割字元串用的,這裡是除去第一個字元

最後,看一下是怎麼生成随機byte數組的:

通過 ng.nextBytes(randomBytes); 可以點進去看到

public synchronized void engineNextBytes(byte[] var1) {
        int var2 = 0;
        byte[] var4 = this.remainder;
        if (this.state == null) {
            byte[] var5 = new byte[20];
            SecureRandom.SeederHolder.seeder.engineNextBytes(var5);
            this.state = this.digest.digest(var5);
        }

        int var7 = this.remCount;
        int var3;
        int var6;
        if (var7 > 0) {
            var3 = var1.length - var2 < 20 - var7 ? var1.length - var2 : 20 - var7;

            for(var6 = 0; var6 < var3; ++var6) {
                var1[var6] = var4[var7];
                var4[var7++] = 0;
            }

            this.remCount += var3;
            var2 += var3;
        }

        while(var2 < var1.length) {
            this.digest.update(this.state);
            var4 = this.digest.digest();
            updateState(this.state, var4);
            var3 = var1.length - var2 > 20 ? 20 : var1.length - var2;

            for(var6 = 0; var6 < var3; ++var6) {
                var1[var2++] = var4[var6];
                var4[var6] = 0;
            }

            this.remCount += var3;
        }

        this.remainder = var4;
        this.remCount %= 20;
    }