Java2008. 9. 26. 22:11

스타시디키는 Checksum 계산 원리만 알면 무작위 번호를 쉽게 생성할 수 있다.

총 13자리 중 맨 끝 번호를 제외한 12자리는 임의의 수를 생성하고,

이 12자리 숫자들을 이용해 계산식에 대입한 결과를 13자리에 붙이면 완성된다.

 

Checksum 계산식에 대해 알아보자.

 

우선 랜덤으로 12자리 숫자를 만든다.
랜덤으로 구한 12자리 숫자들을 각각 하나씩 아래 공식으로 계산하면 13번째자리의 값이 된다.
랜덤으로 구해진 각 자리수를 n이라 하고, 구해야할 값을 c라고 하면,
 
c = c + (n XOR (2 * c))
 
위 식에서 처음 c의 값은 3을 대입하여 구해진 c값을 누적적용하면서 n마다 12번 반복하고 10으로 나눈 나머지, 즉
 c = c % 10
를 구한 값이 13번째자리 값이 된다.
 
예를 들어 랜덤으로 생성한 12자리 값이
123456789123
이라면,
 
c = 3      + (1 ^ (2 * 3     )) = 10
c = 10     + (2 ^ (2 * 10    )) = 32
c = 32     + (3 ^ (2 * 32    )) = 99
c = 99     + (4 ^ (2 * 99    )) = 293
c = 293    + (5 ^ (2 * 293   )) = 884
c = 884    + (6 ^ (2 * 884   )) = 2658
c = 2658   + (7 ^ (2 * 2658  )) = 7973
c = 7973   + (8 ^ (2 * 7973  )) = 23911
c = 23911  + (9 ^ (2 * 23911 )) = 71726
c = 71726  + (1 ^ (2 * 71726 )) = 215179
c = 215179 + (2 ^ (2 * 215179)) = 645535
c = 645535 + (3 ^ (2 * 645535)) = 1936604
 
이와 같이 구해지고,
최종으로 구한 c가 1936604이므로
c / 10 의 나머지 값을 구하면,
 
c = c % 10 = 4
 
최종값은 4가 되므로 끝에 4를 붙이면,
계산식에 맞는 시디키는 1234567891234가 된다.
하이픈(-)을 추가해서 시디키 모양을 만들면 완성

1234-56789-1234

이렇게 생성된 시디키는 정식 배틀넷은 통과하지 못하고 컴에 인스톨시 확인 통과만 가능하다.

 
아래는 콘솔에 10개씩 생성해 주는 소스를 C#과 Java로 구성해 봤다.

원리 확인 및 학습하는데만 참고 하기 바란다.

  

[Java 소스]

 class CDKeyGenerator {
    public static void main(String[] args) {
        System.out.println("Starcraft CD-Key Generator by WinbotCafe");
        for(int i=0; i<10; i++) {
            System.out.println(generateKey());
        }
    }

    private static String generateKey() {
        String rndKey = "";
        for(int i=0; i<12; i++) {
            rndKey += (int)(Math.random() * 10);
            if(i==3 || i==8) rndKey += "-";
        }
        return rndKey + getChecksum(rndKey);
    }

    private static long getChecksum(String generatedKey) {
        long checksum = 3L;
        for(int i=1; i<=generatedKey.length(); i++) {
            if(i != 5 && i != 11) {
                checksum += (Long.parseLong(generatedKey.substring(i-1,i))^(2*checksum));
            }
        }
        return checksum % 10;
    }
}




[C# 소스]

using System;
using System.Text;

namespace StarcraftCDKey
{
    class CDKeyGenerator
    {
        private static Random rnd = new Random();

        public static void Main(string[] args)
        {
            Console.WriteLine("Starcraft CD-Key Generator by WinbotCafe");

            for(int i=0; i<10; i++)
            {
                Console.WriteLine(GenerateKey());
            }
        }

         private static string GenerateKey()
        {
            string rndKey = "";

            for(int i=0; i<12; i++)
            {
                rndKey += rnd.Next(0,9).ToString();
                if(i==3 || i==8) rndKey += "-";
            }

            return rndKey + GetChecksum(rndKey);
        }

         private static long GetChecksum(string rndKey)
        {
            long checksum = 3L;
            try
            {
                for(int i=1; i<=rndKey.Length; i++)
                {
                    if(i != 5 && i != 11)
                    {
                        checksum += (Convert.ToInt64(rndKey.Substring(i-1,1))^(2*checksum));
                    }
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }


            return checksum % 10;
        }
    }
}

 

'Java' 카테고리의 다른 글

로또번호 랜덤생성 자바소스  (0) 2009.03.17
Base64 encode & decode in Java  (0) 2009.03.17
자바 랜덤 문자열 생성  (0) 2009.03.10
JSTL forEach forToken  (0) 2008.10.02
Posted by Main()
Miscellaneous2008. 9. 26. 09:47

<출처>
http://www.zdnet.co.kr/


CD 키

전략 시뮬레이션을 기획 제작하고 있는 게임사 개발팀의 박 팀장.

베틀넷 서비스를 구상하고 있기에 안전한 CD 키를 만들 방법이 없겠냐고 필자에게 물어온 적이 있었다. 아마 조금만 생각하면 쉽게 생각해 낼 수 있었겠지만 마땅히 문서화한 자료를 구하기 힘들었기 때문이었을 것이다. 사실 스타 크래프트의 CD 키 생성툴은 립버전이 활개를 치게 하는데 큰 역할을 했다. 여러 가지 알고리즘이 많이 있겠지만, 보통 이런 번호는 실제 키와 그 키를 암호화한 부분을 합친 것을 생각해 보자. 이 대표적인 예가 주민등록번호다. 주민등록번호는 실제키 12자리에 각 가중치를 줘 더한 값을 10으로 모듈 연산해 얻은 값을 마지막에 붙여 13자리로 이뤄진다.

따라서 12자리를 정한 후 마지막 자리를 10번 반복하면, 주민등록번호에 대한 인증은 뚫리게 된다. 일단 10진수가 위험하다는 것을 느꼈을 것이다. 여기에 알파벳 26자을 동원하면 36가지가 가능한 36진수가 된다. 소문자도 동원할 수 있지만 대소문자 구분까지 하는 것은 유행은 아닌 듯 하니 대소문자 구분은 하지 않고 36진수만 사용하도록 하자.

그리고 생성 규칙은 날짜에 그날 생성된 순서로 하자. 그리고 마지막에 이 값을 모두 더한 값을 끝에 덧붙이도록 하자.

Y0Y1Y2Y3/M0M1/D0D1 S0S1S2S3 H0H1H2

원문은 다음과 같다고 하자. 암호화 알고리즘은 여러 가지가 있지만, 어차피 공개키 방식을 동원할거라면, 어떤 알고리즘을 사용하더라도 어떤 알고리즘을 사용했는지 공개만 하지 않으면 되므로 비교적 구현이 쉬운 DLP(Discrete Logarithm Problem)을 이용하겠다. 지수는 곱셈을 반복하면 되는 것으로 구현이 비교적 간단하다. 다음 식을 보자.

Ax = B (mod n)

간단한 식이지만, 참 많은 규칙이 숨어 있다. A가 소수일때 '0

7x = B (mod 31)

이 정도면 훌륭하다. 36진수를 사용할 것이라고 했는데 31을 사용한 것은 모듈 연산을 소수로 해야 겹치지 않기 때문이다. 예를 들어 다음과 같은 경우를 생각해보자.

31 (mod 8) = 3
32 (mod 8) = 1
33 (mod 8) = 3
...

32가 1이 되면서 계속 3과 1이 반복돼 버린다. 따라서 8이 아닌 소수를 잡아야 한다. 계산을 하기 위한 힌트하나로 다음과 같은식이 성립한다.

Ax+y (mod n) = ( Ax (mod n) )× ( Ay (mod n) )

다음과 같은 예를 들 수 있다.

35(mod 7) = 243 (mod 7) = 5
= 31(mod 7)×34(mod 7) = 3 (mod 7)×11 (mod 7) = 33 (mod 7 ) = 5
= 32(mod 7)×33(mod 7) = 2 (mod 7)×6 (mod 7) = 12 (mod 7 ) = 5
이 속성은 실제 구현시 매우 유용한 속성으로 전값에 곱셈을 하고 바로 모듈연산을 해버리면 값이 작아지므로 작은 범위의 데이터 타입으로도 큰 지수 연산을 가능하게 해준다.

그럼 원문을 200103120003012이라고 해보자. 2001년 3월 12일의 세번째 만들어진 CD 키라는 뜻이다. 그리고 뒤에 012는 앞의 모든 숫자를 더해 만든 해시키다.

70 = 1 (mod 31)
71 = 7 (mod 31)
72 = 18 (mod 31)
73 = 2 (mod 31)
...
따라서 암호문은 다음과 같을 것이다.

( 18, 1, 1, 7, 1, 2, 7, 18, 1, 1, 1, 2, 1, 7, 18)

이 암호문은 아스키 코드 등으로 바꿔 사용하면 될 것이다. 그런데 0이 7개, 1이 4개, 2가 3개이다. 패턴을 읽힐 수 있다. 따라서 자리수별로 가중치를 주자. 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47로 하면 그 문제는 해결될 것이다. 그리고 이렇게 나온 값을 가지고 암호화 패턴을 하나 만들어 뒤에 4자리 정도 붙이자. 그럼 다음과 같은 결과 값이 나올 것이다.

22 = 4 (mod 31)
30 = 1 (mod 31)
50 = 1 (mod 31)
71 = 7 (mod 31)
110 = 1 (mod 31)
133 = 27 (mod 31)
171 = 17 (mod 31)
192 = 20 (mod 31)
230 = 1 (mod 31)
290 = 1 (mod 31)
310 = 1 (mod 31)
373 = 6 (mod 31)
410 = 1 (mod 31)
431 = 12 (mod 31)
472 = 8 (mod 31)

따라서 암호문은 다음과 같다.

( 4, 1, 1, 7, 1, 27, 17, 20, 1, 1, 1, 6, 1, 12, 8 )
( 4, 1, 1, 7, 1, R, H, K, 1, 1, 1, 6, 1, C, 8 )

4117-1RHK-1116-1C8

특성상 지수의 0승이 1이 돼 1이 많은데 실제 사용시에는 지수에 전부 1을 더해서 사용하면, 훨씬 분포도가 좋아 질 것이다. 이 키를 사용자가 입력하면 역으로 로그 연산을 하면 원문을 얻을 수 있다. 앞의 시리얼키를 해시해 나온 값이 해시키와 일치하면 그 키는 유효한 것이다.

네트워크에 연결되지 않은 채 로컬에서만 게임을 즐기는 사람이 많기 때문에 인증서버를 거치지 못하고 단방향 암호함수를 거치는 수밖에 없다.

 

Posted by Main()
Miscellaneous2008. 9. 17. 19:55
사용자 삽입 이미지
여성의 걸음걸이를 살펴보면 성생활을 할 때 오르가슴을 느낀 적이 많은 여성인지 아닌지 등 그 여성의 오르가슴 역사를 추측할 수 있다는 연구결과가 나왔다.

영국 서부스코틀랜드대 스튜어트 브로디 박사팀과 벨기에 연구진은 벨기에 여대생 16명에게 그들의 성생활에 대해 질문지에 응답하도록 하고 공공장소에서 그들의 걸음걸이를 비디오로 촬영했다.

연구진은 설문결과를 제외하고 비디오만 2명의 성의학 교수와 2명의 성의학 전공 조교에게 보여준 결과 여대생들이 설문지에서 응답한 성생활의 내용과 전문가들이 추측한 오르가슴 여부가 일치했다고 밝혔다.

오르가슴을 느낀 적이 많은 여성은 걸을 때 성큼성큼 크게 걸었고 척추의 움직임도 많았다. 오르가슴을 느낀 적이 많은 여성은 걸을 때 골반의 회전력을 이용해 다리를 힘차고 자유롭게 움직였다.

브로디 박사는 “여성은 신체 구조상 오르가슴 경험이 큰지 작은지를 판단하기 쉽다”면서 “여성은 골반 근육에 이상이 있으면 원활히 움직일 수 없어 성생활을 할 때 오르가슴 반응이 약화되는 경향이 있는데 이 근육의 건강상태는 평상시 걸음걸이에도 나타나기 때문에 성생활에서 오르가슴을 많이 느끼는지 아닌지 여부를 알 수 있는 것”이라고 말했다.

그는 또 성적으로 오르가슴을 느낀 적이 있는 여성은 성적인 능력에 더 자신감을 가지게 되기 때문에 이러한 면이 걸음걸이에 그대로 나타난다고 설명했다.

연구진은 성생활을 할 때 오르가슴에 문제가 있는 여성은 걷기 등의 움직임 훈련이나 복식호흡 훈련 그리고 근육 운동 등을 동시에 하면 성기능 치료에 도움이 될 거라고 밝혔다.

이 연구는 ‘성의학저널(The Journal of Sexual Medicine)’ 9월호에 게재됐고 미국 온라인과학저널 사이언스데일리 등이 7일 보도했다.


권병준 기자 (riwoo@kormedi.com)

저작권ⓒ '건강을 위한 정직한 지식' 코메디닷컴 / 무단전재-재배포 금지

'Miscellaneous' 카테고리의 다른 글

컴퓨터 부품 고를때 필요한 기본 상식  (0) 2008.11.01
시디키를 만들어보자  (0) 2008.09.26
‘앞쪽형 인간’이 성공한다.  (0) 2008.09.17
캐공감 작렬  (0) 2008.09.16
Posted by Main()