programing

"aX4j9Z"와 같은 짧은 uid를 생성하는 방법 (JS)

nasanasas 2020. 12. 29. 07:10
반응형

"aX4j9Z"와 같은 짧은 uid를 생성하는 방법 (JS)


내 웹 응용 프로그램 (JavaScript)의 경우 짧은 GUID를 생성하고 싶습니다 (실제로 다른 유형 인 문자열 및 문자열 배열)

내 uid (guids)에 "aX4j9Z"와 같은 것을 원합니다.

따라서 이러한 uid는 웹 전송 및 js 문자열 처리에 충분히 가볍고 거대한 구조 (10k 요소 이하)에 대해서는 매우 고유해야합니다. "매우 고유하다"는 것은 uid 생성 후에이 uid가 구조에 이미 존재하는지 확인하고 존재하는 경우 재생성 할 수 있음을 의미합니다.


사전 패키지 솔루션 ( 패키지 )에 대해서는 @Mohamed의 답변참조하십시오 . 특별한 요구 사항이없는 경우이 페이지의 다른 솔루션 대신이를 선호하십시오.shortid


6 자 영숫자 시퀀스는 10k 컬렉션을 무작위로 인덱싱하기에 충분합니다 (36 6 = 22 억 및 36 3 = 46656).

function generateUID() {
    // I generate the UID from two parts here 
    // to ensure the random number provide enough bits.
    var firstPart = (Math.random() * 46656) | 0;
    var secondPart = (Math.random() * 46656) | 0;
    firstPart = ("000" + firstPart.toString(36)).slice(-3);
    secondPart = ("000" + secondPart.toString(36)).slice(-3);
    return firstPart + secondPart;
}

무작위로 생성 된 UID는 ~ √N 개의 숫자 (생일 패러독스) 생성 후 충돌이 발생하므로 확인없이 안전한 생성을 위해 6 자리가 필요합니다. (구 버전은 확인하지 않으면 1300 개의 ID 이후 충돌이 발생하는 4 자리 만 생성됩니다.) .

충돌 검사를 수행하면 자릿수가 3 또는 4로 줄어들 수 있지만 더 많은 UID를 생성하면 성능이 선형 적으로 감소합니다.

var _generatedUIDs = {};
function generateUIDWithCollisionChecking() {
    while (true) {
        var uid = ("0000" + ((Math.random() * Math.pow(36, 4)) | 0).toString(36)).slice(-4);
        if (!_generatedUIDs.hasOwnProperty(uid)) {
            _generatedUIDs[uid] = true;
            return uid;
        }
    }
}

순차적 생성기를 사용하는 것이 좋습니다 (예를 들어 user134_item1, user134_item2...) 당신은 독창성이 아니라 예측 불가능 성을 필요로합니다. 예측 불가능 성을 복구하기 위해 순차적으로 생성 된 문자열을 "해시"할 수 있습니다.

를 사용하여 생성 된 UID Math.random는 안전하지 않습니다 (어쨌든 클라이언트를 신뢰해서는 안됩니다). 마십시오 하지 미션 크리티컬 한 업무에서의 고유성 또는 예측 불가능에 의존하고 있습니다.


이것에 대한 멋진 npm 패키지도 있습니다 : shortid

놀랍도록 짧은 비 순차적 URL 친화적 인 고유 ID 생성기.

ShortId는 놀랍도록 짧은 비 순차적 URL 친화적 인 고유 ID를 만듭니다. URL 단축기, MongoDB 및 Redis ID 및 기타 사용자가 볼 수있는 모든 ID에 적합합니다.

  • 기본적으로 7-14 개의 URL 친화적 인 문자 : AZ, az, 0-9, _-
  • 비 순차적이므로 예측할 수 없습니다.
  • 클러스터 (자동), 사용자 지정 시드, 사용자 지정 알파벳을 지원합니다.
  • 중복없이 ID를 얼마든지 생성 할 수 있습니다 (하루에 수백만 개).
  • 게임에 적합합니다. 특히 부정 행위에 대해 염려되어 쉽게 추측 할 수있는 ID를 원하지 않는 경우에 적합합니다.
  • ID를 반복하지 않고도 앱을 여러 번 다시 시작할 수 있습니다.
  • Mongo ID / Mongoose ID의 인기있는 대체.
  • Node, io.js 및 웹 브라우저에서 작동합니다.
  • 모카 테스트를 포함합니다.

용법

var shortid = require('shortid');
console.log(shortid.generate()); //PPBqWA9

다음은 대소 문자 구분이 고유하고 모든 위치에서 숫자가 허용되는 경우 3 자의 고유 값 62 ^ 3 (238,328)을 생성합니다. 대소 문자 구분이 필요한 경우 문자 문자열에서 대문자 또는 소문자를 제거하면 35 ^ 3 (42,875) 개의 고유 값이 생성됩니다.

첫 번째 문자가 항상 문자 또는 모든 문자가되도록 쉽게 조정할 수 있습니다.

하지만 최적화 할 수 있으며 제한에 도달하면 ID 반환을 거부 할 수도 있습니다.

var nextId = (function() {
  var nextIndex = [0,0,0];
  var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
  var num = chars.length;

  return function() {
    var a = nextIndex[0];
    var b = nextIndex[1];
    var c = nextIndex[2];
    var id = chars[a] + chars[b] + chars[c];

    a = ++a % num;

    if (!a) {
      b = ++b % num; 

      if (!b) {
        c = ++c % num; 
      }
    }
    nextIndex = [a, b, c]; 
    return id;
  }
}());

이렇게하면 일련의 고유 한 값이 생성됩니다. 모든 값이 소진되었을 때 문자열 길이를 늘려 RobG의 대답을 향상시킵니다.

var IdGenerator = (function () {

    var defaultCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()_-+=[]{};:?/.>,<|".split("");

    var IdGenerator = function IdGenerator(charset) {
        this._charset = (typeof charset === "undefined") ? defaultCharset : charset;
        this.reset();
    };

    IdGenerator.prototype._str = function () {
        var str = "",
            perm = this._perm,
            chars = this._charset,
            len = perm.length,
            i;
        for (i = 0; i < len; i++) {
            str += chars[perm[i]];
        }
        return str;
    };

    IdGenerator.prototype._inc = function () {
        var perm = this._perm,
            max = this._charset.length - 1,
            i;
        for (i = 0; true; i++) {
            if (i > perm.length - 1) {
                perm.push(0);
                return;
            } else {
                perm[i]++;
                if (perm[i] > max) {
                    perm[i] = 0;
                } else {
                    return;
                }
            }
        }
    };

    IdGenerator.prototype.reset = function () {
        this._perm = [];
    };

    IdGenerator.prototype.current = function () {
        return this._str();
    };

    IdGenerator.prototype.next = function () {
        this._inc();
        return this._str();
    };

    return IdGenerator;

}).call(null);

용법:

var g = new IdGenerator(),
    i;

for (i = 0; i < 100; i++) {
   console.log(g.next());
}

This gist contains the above implementation and a recursive version.


var letters = 'abcdefghijklmnopqrstuvwxyz';
var numbers = '1234567890';
var charset = letters + letters.toUpperCase() + numbers;

function randomElement(array) {
    with (Math)
        return array[floor(random()*array.length)];
}

function randomString(length) {
    var R = '';
    for(var i=0; i<length; i++)
        R += randomElement(charset);
    return R;
}

You can shorten a GUID to 20 printable ASCII characters without losing information or the uniqueness of the GUID.

Jeff Atwood blogged about that years ago:
Equipping our ASCII Armor


just randomly generate some strings:

function getUID(len){
    var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
          out = '';

    for(var i=0, clen=chars.length; i<len; i++){
       out += chars.substr(0|Math.random() * clen, 1);
    }

    // ensure that the uid is unique for this page
    return getUID.uids[out] ? getUID(len) : (getUID.uids[out] = out);
}
getUID.uids = {};

ReferenceURL : https://stackoverflow.com/questions/6248666/how-to-generate-short-uid-like-ax4j9z-in-js

반응형