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

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,294
13년 전 조회 984
13년 전 조회 835
13년 전 조회 752
13년 전 조회 916
13년 전 조회 704
13년 전 조회 1,225
13년 전 조회 936
13년 전 조회 634
13년 전 조회 1,234
13년 전 조회 865
13년 전 조회 1,600
13년 전 조회 1,023
13년 전 조회 3,500
13년 전 조회 1,564
13년 전 조회 2,152
13년 전 조회 780
13년 전 조회 434
13년 전 조회 1,115
13년 전 조회 1,906
13년 전 조회 803
13년 전 조회 2,042
13년 전 조회 744
13년 전 조회 1,093
13년 전 조회 1,799
13년 전 조회 1,121
13년 전 조회 777
13년 전 조회 1,478
13년 전 조회 3,789
13년 전 조회 510
13년 전 조회 581
13년 전 조회 766
13년 전 조회 3,906
13년 전 조회 1,253
13년 전 조회 1,424
13년 전 조회 1,441
13년 전 조회 740
13년 전 조회 613
13년 전 조회 759
13년 전 조회 1,575
13년 전 조회 936
13년 전 조회 1,272
13년 전 조회 2,469
13년 전 조회 930
13년 전 조회 1,253
13년 전 조회 1,364
13년 전 조회 713
13년 전 조회 3,466
13년 전 조회 1,224
13년 전 조회 2,739
13년 전 조회 1,077
13년 전 조회 765
13년 전 조회 811
13년 전 조회 687
13년 전 조회 1,261
13년 전 조회 1,348
13년 전 조회 2,662
13년 전 조회 4,245
13년 전 조회 703
13년 전 조회 3,268
13년 전 조회 645
13년 전 조회 1,105
13년 전 조회 700
13년 전 조회 1,079
13년 전 조회 1,828
13년 전 조회 1,143
13년 전 조회 620
13년 전 조회 1,285
13년 전 조회 891
13년 전 조회 1,294
13년 전 조회 1,765
13년 전 조회 1,065
13년 전 조회 720
13년 전 조회 1,906
13년 전 조회 1,185
13년 전 조회 771
13년 전 조회 713
13년 전 조회 1,072
13년 전 조회 610
13년 전 조회 1,721
13년 전 조회 1,005
13년 전 조회 1,022
13년 전 조회 654
13년 전 조회 1,291
13년 전 조회 2,101
13년 전 조회 619
13년 전 조회 517
13년 전 조회 690
13년 전 조회 3,283
13년 전 조회 752
13년 전 조회 1,306
13년 전 조회 1,081
13년 전 조회 730
13년 전 조회 7,729
13년 전 조회 1,103
13년 전 조회 1,751
13년 전 조회 753
13년 전 조회 1,088
13년 전 조회 920
13년 전 조회 1,891
🐛 버그신고