[C] 纯文本查看 复制代码
#include <iostream>
#include <math.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef unsigned long long UINT64;
typedef unsigned int UINT32;
typedef unsigned char UINT8;
union IF {
UINT32 I;
float F;
};
UINT32 _STR_PAUSE[] = {0x3E5C8DC9, 0x3E3F03F0, 0x3E666666, 0x3E627627, 0x3E46E46E, 0x0};
UINT32 _HEX_DIG[] = {0x00039A50, 0x0003AD87, 0x0003C0BE, 0x0003D3F5, 0x0003E72C, 0x0003FA63,
0x00040D9A, 0x000420D1, 0x00043408, 0x0004473F, 0x000747D7, 0x00075B0E,
0x00076E45, 0x0007817C, 0x000794B3, 0x0007A7EA };
UINT32 _STR_IN_FLAG[] = {0x35B7BF3E, 0x50F1CF84, 0x526A9220, 0x561878A6, 0x555C1758, 0x178C29C0,
0x4B0EC514, 0x4F790CE8, 0x4760DE8E, 0x4BCB2662, 0x2AAE0BAC, 0x178C29C0, 0x0};
UINT32 _STR_IN_UID[] = {0x3EA0697A, 0x3EF1B77C, 0x3EF61C91, 0x3F008CA3, 0x3EFEE6BB, 0x3E0CA29C,
0x3F008CA3, 0x3EE6BAC8, 0x3EDBBE14, 0x3E7EE6BB, 0x3E0CA29C, 0x0};
UINT32 _STR_OK[] = {0x3F1F3E7D, 0x3F172E5D, 0x3EB162C6, 0x3E810204, 0x3F73E7D0, 0x3F5FBF7F, 0x3F6BD7AF, 0x3E810204,
0x3F43870E, 0x3F65CB97, 0x3F4B972E, 0x3E810204, 0x3F65CB97, 0x3F53A74F, 0x3F4F9F3E, 0x3F51A347,
0x3F69D3A7, 0x3EB972E6, 0x0};
UINT32 _STR_ERR[] ={0x0078911A, 0x00C73284, 0x00C73284, 0x00C1F48E, 0x00C73284, 0x004CE218, 0x0037EA40, 0x00C3B3E0,
0x00BCB698, 0x00B07B5A, 0x00A97E12, 0x00C8F1D6, 0x00B07B5A, 0x0037EA40, 0x00CAB128, 0x00C73284,
0x00D36DC2, 0x0037EA40, 0x00A97E12, 0x00B3F9FE, 0x00A97E12, 0x00B778A2, 0x00C0353C, 0x005060BC, 0};
UINT8 _initreciptable8x8[] ={0xF1, 0xD8, 0xC3, 0xB2, 0xA4, 0x98, 0x8D, 0x84};
UINT8 _initreciptable16x8[] = {0xF8, 0xEA, 0xDD, 0xD2, 0xC8, 0xBF, 0xB6, 0xAE, 0xA7, 0xA1, 0x9B, 0x95, 0x90, 0x8B, 0x86, 0x82};
UINT8 _initreciptable8x8_0[] = {0xF1, 0xD8, 0xC3, 0xB2, 0xA4, 0x98, 0x8D, 0x84};
#define MAX_UID 3000000
UINT32 _rng_seed = 0;
void tip_uid();
void tip_flag();
void tip_error();
void tip_ok();
UINT64 _getapproxrecip16x8_32(UINT32 arg);
bool check(UINT32 uid, char * flag);
bool get_flag(UINT32 uid, char * flag);
bool get_flag_part(UINT32 uid_part, char * flag);
int main(int argc, char** argv) {
printf("Hello world.\n");
//UINT64 ar = _getapproxrecip16x8_32(0x99B80000);
//printf("ar = %I64X\n", ar);
tip_uid();
//UINT32 uid = 1024510; //// "faba9cb5ad6b01f8"
//UINT32 uid = 1034567; //// "0d0e487c7a57a036"
UINT32 uid = 1234567; //// "2b9f32d2cd6b6f5d"
printf("%u\n", uid);
char flag[] = "0123456789ABCDEF\0";
bool ret = get_flag(uid, flag);
printf("flag = %s\n", flag);
/*
tip_flag();
printf("\n");
tip_error();
printf("\n");
tip_ok();
printf("\n");
*/
/*
if(uid<MAX_UID) {
bool isOK = check(uid, flag);
if(isOK) {
tip_ok();
} else {
tip_error();
}
} else {
tip_error();
}
printf("\n");
*/
return 0;
}
void tip_uid() {
IF m1, m2;
m2.I = 0x3B8CA29C;
int i=0;
while(_STR_IN_UID[i] != 0) {
m1.I = _STR_IN_UID[i++];
float a = ( m1.F / m2.F);
//int b = round(a);
int b = trunc(a);
printf("%c", (char)b);
}
}
void tip_flag() {
for(int i=0; i<13; i++) {
char output_ch = 0;
int f = _STR_IN_FLAG[i];
if(f>12345677) {
UINT32 a = 2918332797; // _getapproxrecip16x8_32(12345678 * 256)
UINT64 aa = (UINT64)f * a;
//printf("aa = %I64X\n", aa);
UINT32 ch = (UINT32)(aa >> 55);
UINT32 b = f - ch * 12345678;
//printf("ch = 0x%x\n", ch);
UINT32 c = b;
//printf("%u\n", c);
output_ch = (char)ch;
//printf("ch = %c\n", (char)output_ch);
if(b>12345677) {
b -= 12345678;
UINT64 d = (UINT64)b * 1459166399; /// 1459166398 + 1
if((d & 0x40000000000000) == 0) {
output_ch ++;
}
while(b>12345677) {
b -= 12345678 * 2;
output_ch += 2;
}
//printf("2: %u\n", output_ch);
}
}
printf("%c", (char)output_ch);
}
}
void tip_error() {
for(int i=0; i<24; i++) {
char output_ch = 0;
int e = _STR_ERR[i];
if(e>114513) {
UINT32 a = 2457996198; // _getapproxrecip16x8_32(114514 * 32768)
UINT64 aa = (UINT64)e * a;
//printf("aa = %I64X\n", aa);
UINT32 ch = (UINT32)(aa >> 48);
UINT32 b = e - ch * 114514;
//printf("ch = 0x%x\n", ch);
UINT32 c = b;
//printf("%u\n", c);
output_ch = (char)ch;
//printf("ch = %c\n", (char)output_ch);
if(b>114513) {
b -= 114514;
UINT64 d = (UINT64)b * 2457996199; // 2457996198 + 1
if((d & 0x40000000000000) == 0) {
output_ch ++;
}
while(b>114513) {
b -= 114514 * 2;
output_ch += 2;
}
//printf("2: %u\n", output_ch);
}
}
printf("%c", (char)output_ch);
}
}
void tip_ok() {
IF m1;
float m2 = 127;
for(int i=0; i<18; i++) {
m1.I = _STR_OK[i];
float a = ( m1.F * m2);
//int b = round(a);
int b = trunc(a);
printf("%c", (char)b);
}
}
UINT64 _getapproxrecip16x8_32(UINT32 arg) {
UINT32 a = _initreciptable16x8[arg / 0x8000000 & 0x0F] * 0x1000000;
UINT64 b = -(UINT32)(((UINT64)a * arg) >> 32);
UINT64 c = ((b * a)>>32) * 2;
UINT32 d = -((arg * c) >> 32);
UINT64 e = d * c;
UINT64 f = (e >> 32) * 2;
UINT32 g = (UINT32)((arg * f)>>32);
UINT64 h = (~(g)) * f;
return (h >> 31);
}
void rand_generator(UINT32 seed, UINT32 &rnd1, UINT32 &rnd2) {
float max_uid = MAX_UID;
float flt_uid = seed;
float a = flt_uid / max_uid;
float b = a - 0.5;
IF stu_b;
stu_b.F = b;
if(b>0) {
stu_b.I --;
} else {
stu_b.I ++;
}
float d = stu_b.F;
UINT32 d2 = stu_b.I;
IF stu_e;
stu_e.I = 0x3C9D89D9; /// 0.01923076994717121
float e = stu_e.F;
float f = e * flt_uid;
//UINT32 g = round(f);
UINT32 g = trunc(f);
if(f>28846) {
g /= 2;
}
UINT32 h = g + 1024;
IF stu_j;
stu_j.F = d;
UINT32 j = stu_j.I;
if(h>1) {
int k = 1;
do {
j = j * 134775813 + 1;
k++;
} while(h != k);
}
rnd1 = j * 134775813 + 1; /// 0xC784E0D0
UINT32 k = rnd1 * 134775813 + 1;
_rng_seed = k;
UINT32 u = rnd1 + d2;
UINT32 v = u + k;
rnd2 = (v<<16) | (v>>16);
}
bool get_flag(UINT32 uid, char * flag) {
//// random
UINT32 rnd1=0, rnd2=0;
rand_generator(uid, rnd1, rnd2);
//printf("rnd1 = 0x%08X, rnd2 = 0x%08X\n", rnd1, rnd2);
//// part 1
bool ret1 = get_flag_part(rnd1, &flag[0]);
//// part 2
bool ret2 = get_flag_part(rnd2, &flag[8]);
return ret1 && ret2;
}
bool get_flag_part(UINT32 uid_part, char * flag) {
int i = 0;
do {
//char ch_a = flag[i];
UINT32 flag_ch=0;
UINT32 p = _HEX_DIG[uid_part & 0x0F];
if(p>4918) {
UINT64 ar = _getapproxrecip16x8_32(0x99B80000);
//UINT32 ar_a = 0xD52B24CA;
UINT32 ar_a = (UINT32)(ar);
//UINT32 ar_d = 0x6A959265;
UINT64 q = (UINT64)p * ar_a;
flag_ch = (UINT64)(q >> 44);
UINT32 r = (UINT32)(flag_ch * 4919);
UINT32 s = p - r;
if(s>4918) {
s -= 4919;
UINT64 t = (UINT64)s * 894093619;
if(( t & 0x040000000000) == 0) {
flag_ch ++;
if(s>4918) {
do {
s -= 9838;
flag_ch+=2;
} while(s > 4918);
}
}
}
}
uid_part = uid_part / 16; /// l>>=4;
//printf("%c", flag_ch);
flag[i] = (char)flag_ch;
i++;
} while(i<8);
return true;
}
bool check(UINT32 uid, char * flag) {
return true;
}