스타시디키는 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 |