ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Random Id generator
    Programming 2022. 12. 30. 10:03
    import { randomFillSync } from 'crypto'
    
    const POOL_SIZE_MULTIPLIER = 128
    let pool, poolOffset
    
    function fillPool(bytes) {
        if (!pool || pool.length < bytes) {
            pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)
            randomFillSync(pool)
            poolOffset = 0
        } else if (poolOffset + bytes > pool.length) {
            randomFillSync(pool)
            poolOffset = 0
        }
        poolOffset += bytes
    }
      
    
    function random(bytes) {
        // `-=` convert `bytes` to number to prevent `valueOf` abusing
        fillPool((bytes -= 0))
        return pool.subarray(poolOffset - bytes, poolOffset)
    }
    
    
    function customRandom(alphabet, defaultSize, getRandom) {
        // mask: id 생성하기 위해 필요하고 입력한 알파벳의 길이에 가까움
        let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
      
        // 랜덤 생성기 호출은 비싼 비용이 들기 때문에 추가적인 바이트를 미리 요청함
        // 자리마다 랜덤 알파벳을 추가하지만 bytes[i] & mask 의 인덱스 값이 입력된 알파벳의 길이보다 크면 다시 요청해야함
        // 대략적으로 1.6 * size (mask = alphabet.length + 1)
        // 1.6일때 최상의 퍼포먼스를 보임
        let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)
      
        return (size = defaultSize) => {
            let id = ''
            while (true) {
                let bytes = getRandom(step)
                let i = step
                while (i--) {
                console.log(`bytes[i] & mask - random index: ${bytes[i] & mask} out of ${mask}, do it again if random index === mask after adding '' `) 
                // 1. 버퍼에 숫자를 가져오고 (두자리)
                // 2. mask 는 입력된 알파벳 길이 + 1로
                // 3. 두 숫자를 바이트 &를 하면 2진수로 변경하여 둘다 1인 자리에서만 더해짐 = 더해진 수가 mask보다 큰 숫자가 나올 확률은 작음
                // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND
                id += alphabet[bytes[i] & mask] || ''
                if (id.length === size) return id
                }
            }
        }
    }
      
    
    function customAlphabet(alphabet, length) {
        return customRandom(alphabet, length, random)
    }
    
    console.log(customAlphabet('1234567890abcdefghijklnmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 10)())
    console.log(customAlphabet('1234567890abcdefghijklnmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 10)())

    'Programming' 카테고리의 다른 글

    디자인 패턴  (0) 2022.12.23
    [책] 함께 자라기 - 1장  (0) 2021.12.11
    [TEST] 1. 테스트를 시작하게 된 계기  (0) 2021.10.23
Designed by Tistory.