-
-
原创]参赛 :)
-
发表于: 2007-8-25 01:25 5389
-
VC6 Project 源码 和 keygen.exe 在附件 keygen.rar 里.
// 主要程序: genkey.cpp
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "genkey.h"
typedef int int32_t;
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
#define MAX_TIMES 4096
static char m_codes[ MAX_TIMES ];
static int m_count = 0;
/**
* 根据注册名计算出一个整数
*/
static uint32_t sum_name(const char *name)
{
const char *p;
int32_t sum = 0x13572468;
for (p = name; *p; p++)
{
sum += (*p);
sum *= 0x3721273;
sum += 0x24681357;
sum = (sum >> 7) | ( ((uint32_t)sum) << 0x19);
}
return sum;
}
/**
* 将 bits数组的第 pos 位取反,也就是 bits[pos] ^= 1.
*
* 为将 pos 位取反,必须先:
* 1. bits[pos - 1] = 1
* 2. bits[1] 到 bits[pos - 2] 都为 0
* 这个函数通过递归调用来满足这两个条件.
*
* @note 未做递归深度检查. CrackMe2 中序列号最长 4096 (就是前面定义的 MAX_TIMES),这里假设不会超过这个值.
*/
static void xor(uint8_t bits[10],int pos)
{
int i;
/// 递归结束条件
if (pos == 1)
{
bits[1] ^= 1;
m_codes[m_count++] = 1;
return;
}
/// 先递归调用来满足条件 1
if ( bits[pos - 1] == 0 )
{
xor(bits,pos - 1);
}
/// 再递归调用来满足条件2
for (i = pos - 2; i; i--)
{
if ( bits[i] != 0 )
{
xor(bits,i);
}
}
/// 2 个条件满足了,现在可以将第 pos 位取反了
bits[pos] ^= 1;
/// 记录第几步改变了第几位,后面根据这个生成序列号
m_codes[m_count++] = pos;
}
/**
* 对话框窗口函数调用这个得到序列号
*/
char *genkey(const char *name)
{
int i,v;
uint8_t bits[10],tbl[32];
uint32_t sum;
m_count = 0;
memset(bits,0,sizeof(bits));
memset(m_codes,0,sizeof(m_codes));
/// 根据 name 计算出一个整数
sum = sum_name(name);
/// 生成 8 个元素的 bit 数组
for (i = 1; i < 9; i++)
{
bits[i] = ( (sum >> i) & 1 );
}
bits[9] = 1;
/// 预先计算出一个转换表
for (i = 0; i < 0x1F; i++)
{
tbl[i] = (sum >> (i % 0x1F)) % 10;
}
/**
* 算法思路是: 依次使 9,8,7,...,1 位变成 0. 因为,假如使第 9 位变成 0 了,
* 那么再把第 8 位变成 0 时就不需要考虑第 9 位了. 同样,第 8 位变成 0 后,
* 再改变第 7 位时就不需要考虑 8,9 位. 问题难度将逐步降低,直到最终解决,
* 而且,这个思路可以递归实现.
*/
for (i = 9; i; i--)
{
if ( bits[i] != 0 )
{
xor(bits,i);
}
}
/// 根据每一步改变了第几位,和前面计算出的转换表 (tbl) 计算出序列号
for (i = 0; i < m_count; i++)
{
v = m_codes[i] - tbl[ i % 0x1F ];
m_codes[i] = '0' + (v >=0 ? v : v + 10);
}
m_codes[m_count] = '\0';
return m_codes;
}
// 主要程序: genkey.cpp
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "genkey.h"
typedef int int32_t;
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
#define MAX_TIMES 4096
static char m_codes[ MAX_TIMES ];
static int m_count = 0;
/**
* 根据注册名计算出一个整数
*/
static uint32_t sum_name(const char *name)
{
const char *p;
int32_t sum = 0x13572468;
for (p = name; *p; p++)
{
sum += (*p);
sum *= 0x3721273;
sum += 0x24681357;
sum = (sum >> 7) | ( ((uint32_t)sum) << 0x19);
}
return sum;
}
/**
* 将 bits数组的第 pos 位取反,也就是 bits[pos] ^= 1.
*
* 为将 pos 位取反,必须先:
* 1. bits[pos - 1] = 1
* 2. bits[1] 到 bits[pos - 2] 都为 0
* 这个函数通过递归调用来满足这两个条件.
*
* @note 未做递归深度检查. CrackMe2 中序列号最长 4096 (就是前面定义的 MAX_TIMES),这里假设不会超过这个值.
*/
static void xor(uint8_t bits[10],int pos)
{
int i;
/// 递归结束条件
if (pos == 1)
{
bits[1] ^= 1;
m_codes[m_count++] = 1;
return;
}
/// 先递归调用来满足条件 1
if ( bits[pos - 1] == 0 )
{
xor(bits,pos - 1);
}
/// 再递归调用来满足条件2
for (i = pos - 2; i; i--)
{
if ( bits[i] != 0 )
{
xor(bits,i);
}
}
/// 2 个条件满足了,现在可以将第 pos 位取反了
bits[pos] ^= 1;
/// 记录第几步改变了第几位,后面根据这个生成序列号
m_codes[m_count++] = pos;
}
/**
* 对话框窗口函数调用这个得到序列号
*/
char *genkey(const char *name)
{
int i,v;
uint8_t bits[10],tbl[32];
uint32_t sum;
m_count = 0;
memset(bits,0,sizeof(bits));
memset(m_codes,0,sizeof(m_codes));
/// 根据 name 计算出一个整数
sum = sum_name(name);
/// 生成 8 个元素的 bit 数组
for (i = 1; i < 9; i++)
{
bits[i] = ( (sum >> i) & 1 );
}
bits[9] = 1;
/// 预先计算出一个转换表
for (i = 0; i < 0x1F; i++)
{
tbl[i] = (sum >> (i % 0x1F)) % 10;
}
/**
* 算法思路是: 依次使 9,8,7,...,1 位变成 0. 因为,假如使第 9 位变成 0 了,
* 那么再把第 8 位变成 0 时就不需要考虑第 9 位了. 同样,第 8 位变成 0 后,
* 再改变第 7 位时就不需要考虑 8,9 位. 问题难度将逐步降低,直到最终解决,
* 而且,这个思路可以递归实现.
*/
for (i = 9; i; i--)
{
if ( bits[i] != 0 )
{
xor(bits,i);
}
}
/// 根据每一步改变了第几位,和前面计算出的转换表 (tbl) 计算出序列号
for (i = 0; i < m_count; i++)
{
v = m_codes[i] - tbl[ i % 0x1F ];
m_codes[i] = '0' + (v >=0 ? v : v + 10);
}
m_codes[m_count] = '\0';
return m_codes;
}
赞赏
他的文章
- [求助] 有什么真正任意精度的整数运算库? 2766
- [原创]我的第四题解法 6846
- [原创]第二阶段第四题 答案提交 14910
- [原创]第二阶段第二题: 答案提交 6538
- [原创]第二阶段第一题 答案提交 10818
看原图
赞赏
雪币:
留言: