시리얼 생성시 만족해야 할 조건

1. 연속된 번호로 생성될 확률이 작아야 한다.
2. 생성시 중복된 번호가 나올확률이 작아야 한다.
3. 알고리즘을 알고 있더라도 동일 시리얼을 만들어내기 어려워야 한다.
4. 사람이 쉽게 유추할수 있으면 안된다.
5. 우연히 아무렇게나 입력해도 맞을 확률이 낮아야 한다.

예를 들어
혜택이 많은 유료 서비스를 이용하기 위한 시리얼이라면
사람들이 충독적으로 숫자몇개를 더하고 빼서
유추될수 있으면 좋지 않은 시리얼 입니다.

웹에서 시리얼 번호를 받고 체크를 할시에
하루에 실패를 몇번 이상 하면 안된다하는 정도의 체크는 필수적으로 들어가야 합니다.
악의적으로 루프로 돌릴수도 있기 때문에 그렇습니다.


아래의 생성 함수에서는
$serial = str_replace('.', '', (string)bcmul(bcmul((float)$usec * 10000000 , (float)$sec) , get_rand_number(4)));
이것이 핵심인데
bcmul((float)$usec * 10000000 , (float)$sec)
자체로도 unique 한 숫자가 만들어집니다.
하지만 알고리즘을 알고있을시 충분히 악의적으로 생성할수 있는 가능성이 많습니다.
그래서 거기다가 다시 랜덤한 숫자를 곱해주는데
get_rand_number(4)
이것은 자리수가 높을수록 동일한 시리얼을 만들기 어려워집니다.
시리얼 생성 레벨 정도로 이해하시면 될듯합니다.
|

댓글 3개

여기에도 '딴지'를 좀 걸겠습니다. ^^;

제가 유창화님 글에 '딴지'를 거는 이유는,
유창화님의 코드가, '난수발생'부분과 '시리얼코드화' 하는 부분이 섞여있는데
난수발생부분에서 사용하시는 방법 (본 글의 내용에 해당) 이
기존 난수발생기보다 낫다는 것을 인정할 수 없기 때문입니다.
(예를 들어, 위 코드의 리턴값은 항상 0으로 끝납니다. 그것도 가끔 여러개..
물론, $usec에 곱하는 값을 한자리 낮추면 해결되기는 합니다만..)

저도 유창화님 글 이전에는 아무 생각없이 rand 써왔고,
유창화님 덕분에 php 난수발생기 부분에 대해서 더 이해를 할 수 있게 감사하게 생각하고 있습니다.
하지만, mt_rand라는 2^19937-1의 주기를 가진 '괜찮은' 난수발생기를 두고
( http://ko.wikipedia.org/wiki/%EB%A9%94%EB%A5%B4%EC%84%BC_%ED%8A%B8%EC%9C%84%EC%8A%A4%ED%84%B0 )
굳이 '검증되지 않은' 난수발생 방법을 사용해야 할 이유가 있는가 하는 것입니다.

제가 '검증되지 않았다'고 말씀드린 이유는,
유창화님이, (전체 시리얼키) 백만번 생성 중 반복이 발생하지 않았다고 하셨지만,
이는, 유창화님이 정리하신 '시리얼 생성시 조건' 중 2번만 해당하기 때문입니다.
(그리고, 제 실험에서는 10만번당 작은수(1~7)의 중복이 꾸준히 발견되었습니다.. 만 이는 서버나 라이브러리마다의 특성이라고 생각합니다.)
기존 난수발생기들은, 위와 같은 '시리얼 생성시 조건'과 비슷하거나 더 타이트한 조건에 맞게 설계되도록 되어있습니다. (그런데 rand 함수가 왜 그 모양인지는 모르겠네요..^^;)

마지막으로, 유창화님의 시리얼 생성시 조건 3번에 공감합니다.
즉, mt_rand 가 뛰어나다고 해도, 알려진 알고리즘보다는
기존 알고리즘에 한두 스텝을 더한 방법이 더 낫다고 생각합니다. ^^
정말 심도 있고 좋은 의견 감사합니다.

거기도 0을 하나 더 햇군요. 0을 하나 빼는게 맞습니다.
원래 정수로 만들고자 함인데 0을 하나 더 했군요......
감사합니다.

난수 발생기 부분은
엄밀하게 말하면 제가 만든 것은 완전한 난수 발생기가 아닙니다.

원래의 정확한 의도는
시간(microtime)은 계속해서 흐르기때문에
지난 시간 보다 작은 현재값이 현재에 나올수 없습니다.

또 거기다가 1000 이상의 4자리 숫자를 곱하기 때문에 이미 생성된 숫자가 나올수 없다는데 착안되어진 것입니다.
(지금은 조금 바뀌엇지만 원래 제가 의도한것은 이것입니다.)

마이크로타임 자체가 중복될수 없는 유니크한 값이므로 랜덤한 4자리 숫자를 곱할 필요는 없지만
앞자리 숫자를 유동적으로 출력하기 위함과 연번을 피하기 위해서 곱해진 것입니다.

아무튼 그러한 이유가 중복과 연번을 피하고자 함이 핵심입니다.

랜덤 함수는 말그대로 랜덤한 숫자를 만들어줄 뿐이지 매번 중복되지 않는 숫자를 만드는것은 아니기 때문에
전진님이 말한 그런 식의 방법은 사용하지 않은 것입니다.
랜덤 함수는 자릿수가 크면 클수록 그 확률은 줄어들겟지만
위에서 말한바와 같이 중복되거나 연번이 생성될 확률은 존재합니다.

제가 만든것이 mt_rand 보다 더 낫다는 그런뜻은 애초에 없었으며
또 용도가 다르므로 쓰지 않은 것이라는 점과
알고리즘 차원에서 이해해 주시면 좋겠습니다.



아무튼 좋은 의견 감사드립니다.
저도 많은 도움이 되었습니다.
네 ^^
저도 rand 함수나 mt_rand 함수 와 유창화님 코드를 비교할 생각은 없었습니다.
(근데 위 제 댓글을 보니 그런 느낌이.. 그랬다면 죄송합니다.)
유창화님 수준의 코드를 만들 수 있는 분들은 많지 않습니다. (저는 근처도 못가고요..^^;)
연번이나 중복이 거의 없으면서도, 난수 발생한번으로 16자리 키를 만드시는 코드는, 오랜 경험과 많은 지식에서 나온 훌륭한 코드라고 생각하고 있습니다.
아마 기존 난수발생기도 유창화님 코드와 비슷한 내부 알고리즘을 구현했을 거라고 생각합니다.

다시한번 공부거리를 주셔서 감사드리고 있습니다. ^^*
댓글을 작성하시려면 로그인이 필요합니다. 로그인

프로그램

+
제목 글쓴이 날짜 조회
13년 전 조회 1,291
13년 전 조회 977
13년 전 조회 832
13년 전 조회 748
13년 전 조회 913
13년 전 조회 700
13년 전 조회 1,220
13년 전 조회 931
13년 전 조회 629
13년 전 조회 1,229
13년 전 조회 859
13년 전 조회 1,597
13년 전 조회 1,021
13년 전 조회 3,494
13년 전 조회 1,560
13년 전 조회 2,150
13년 전 조회 778
13년 전 조회 429
13년 전 조회 1,112
13년 전 조회 1,903
13년 전 조회 798
13년 전 조회 2,036
13년 전 조회 736
13년 전 조회 1,089
13년 전 조회 1,794
13년 전 조회 1,118
13년 전 조회 775
13년 전 조회 1,476
13년 전 조회 3,785
13년 전 조회 505
13년 전 조회 578
13년 전 조회 759
13년 전 조회 3,904
13년 전 조회 1,246
13년 전 조회 1,421
13년 전 조회 1,436
13년 전 조회 735
13년 전 조회 609
13년 전 조회 755
13년 전 조회 1,569
13년 전 조회 933
13년 전 조회 1,267
13년 전 조회 2,466
13년 전 조회 927
13년 전 조회 1,251
13년 전 조회 1,360
13년 전 조회 708
13년 전 조회 3,462
13년 전 조회 1,222
13년 전 조회 2,736
13년 전 조회 1,075
13년 전 조회 763
13년 전 조회 808
13년 전 조회 680
13년 전 조회 1,258
13년 전 조회 1,345
13년 전 조회 2,658
13년 전 조회 4,240
13년 전 조회 698
13년 전 조회 3,261
13년 전 조회 641
13년 전 조회 1,100
13년 전 조회 695
13년 전 조회 1,075
13년 전 조회 1,822
13년 전 조회 1,139
13년 전 조회 617
13년 전 조회 1,280
13년 전 조회 890
13년 전 조회 1,289
13년 전 조회 1,765
13년 전 조회 1,063
13년 전 조회 715
13년 전 조회 1,903
13년 전 조회 1,180
13년 전 조회 766
13년 전 조회 710
13년 전 조회 1,069
13년 전 조회 605
13년 전 조회 1,717
13년 전 조회 1,000
13년 전 조회 1,019
13년 전 조회 651
13년 전 조회 1,290
13년 전 조회 2,098
13년 전 조회 614
13년 전 조회 512
13년 전 조회 684
13년 전 조회 3,279
13년 전 조회 745
13년 전 조회 1,304
13년 전 조회 1,077
13년 전 조회 725
13년 전 조회 7,727
13년 전 조회 1,098
13년 전 조회 1,748
13년 전 조회 748
13년 전 조회 1,083
13년 전 조회 915
13년 전 조회 1,886
🐛 버그신고