| 9 |
*/ |
*/ |
| 10 |
|
|
| 11 |
#include <assert.h> |
#include <assert.h> |
|
#include <ctype.h> |
|
|
#include <errno.h> |
|
|
#include <limits.h> |
|
|
#include <stdarg.h> |
|
| 12 |
#include <stddef.h> |
#include <stddef.h> |
| 13 |
#include <stdio.h> |
#include <stdio.h> |
|
#include <stdlib.h> |
|
|
#include <string.h> |
|
| 14 |
#include <time.h> |
#include <time.h> |
| 15 |
#include <sys/timeb.h> |
#include <sys/timeb.h> |
|
#include <sys/types.h> |
|
|
|
|
|
#ifndef __ICL |
|
|
#include <unistd.h> |
|
|
#include <libgen.h> |
|
|
#endif /* not __ICL */ |
|
|
|
|
|
#include <limits.h> |
|
|
#ifdef REON |
|
|
#ifdef ONI |
|
|
#include <onigposix.h> |
|
|
#else /* ONI */ |
|
|
/* #include <rxposix.h> */ |
|
|
#include <regex.h> |
|
|
#endif /* ONI */ |
|
|
#endif /* REON */ |
|
| 16 |
|
|
| 17 |
#if defined(WIN32) |
#if defined(WIN32) |
| 18 |
|
|
| 25 |
|
|
| 26 |
#endif |
#endif |
| 27 |
|
|
|
#include "config.h" |
|
|
#include "cp932.h" |
|
|
#include "crypt64.h" |
|
| 28 |
#include "desconst.h" |
#include "desconst.h" |
| 29 |
#include "expr_parse.h" |
#include "expr_parse.h" |
| 30 |
|
#include "hit.h" |
| 31 |
|
#include "key.h" |
| 32 |
|
#include "log.h" |
| 33 |
#include "scoreboard.h" |
#include "scoreboard.h" |
| 34 |
#include "synth.h" |
#include "synth.h" |
|
#include "tr64.h" |
|
|
#include "translate.h" |
|
| 35 |
#include "util.h" |
#include "util.h" |
|
#include "wdict.h" |
|
|
|
|
|
#define TRIP_LEN 10 |
|
|
|
|
|
#define MAKAI_TRUE 1 |
|
|
#define MAKAI_FALSE 0 |
|
|
|
|
|
#define MIN_THREAD 1 |
|
|
#define MAX_THREAD 32 |
|
|
int nThread = 0; |
|
|
uint64_t pmask = 0; |
|
|
|
|
|
#define MIN_UME 3 |
|
|
#define MAX_UME 6 |
|
|
unsigned char umeStr[10]; |
|
|
int umeLen; |
|
|
|
|
|
FILE *nfp; /* 全数 */ |
|
|
FILE *cfp; /* ち */ |
|
|
FILE *tfp; /* ↑以外の特殊検索 */ |
|
|
#ifdef REON |
|
|
FILE *rfp; /* 正規表現 */ |
|
|
#endif /* REON */ |
|
| 36 |
|
|
| 37 |
/* |
static HANDLE mutex_key; |
|
Cygwin 32bit |
|
|
time_t = long = int |
|
|
INT_MIN -2147483648 |
|
|
INT_MAX 2147483647 |
|
|
(2009 - 1970) * 365 * 24 * 60 * 60 = 1229904000 |
|
|
2147483647 - 1229904000 = 917579647 |
|
|
10y * 365 * 24 * 60 * 60 = 315360000 |
|
|
|
|
|
perl -e 'use POSIX;printf(strftime("%Y/%m/%d %T\n",localtime (1234567890)));' |
|
|
*/ |
|
|
#define MIN_SOFF -1229904000 |
|
|
#define MAX_SOFF 315360000 |
|
|
unsigned int seed; |
|
|
int seedOffset; |
|
|
int verbose; |
|
|
|
|
|
#define MAX_GEAR 10 |
|
|
#define MIN_GEAR 1 |
|
|
#define DEF_GEAR 10 |
|
|
int gear; |
|
|
|
|
|
#ifdef KEYLOG |
|
|
#define KEY_LOG_FILE "keylog.txt" |
|
|
int keyLog = MAKAI_FALSE; |
|
|
#endif /* KEYLOG */ |
|
|
|
|
|
#ifdef SELF |
|
|
#define SELF_LIM_CNT 50 |
|
|
#define SELF_LIM_SEC 60 * 60 * 1000 /* 1h */ |
|
|
#endif /* SELF */ |
|
|
|
|
|
unsigned char saltChar[2]; |
|
|
|
|
|
#ifdef ALLKEY |
|
|
unsigned char fixedSaltChar[2]; |
|
|
#endif /* ALLKEY */ |
|
| 38 |
|
|
| 39 |
/* CRYPT64 記述子 */ |
/* CRYPT64 記述子 */ |
| 40 |
static |
static |
| 43 |
&crypt64_desc, |
&crypt64_desc, |
| 44 |
}; |
}; |
| 45 |
|
|
| 46 |
/* 鍵クラス */ |
/* 速度評価用 */ |
| 47 |
static |
static int n_cpus; |
| 48 |
struct |
static uint64_t loop_cpu[1024]; |
|
{ |
|
|
unsigned short map[256]; |
|
|
} kcls[8 + 8]; |
|
|
|
|
|
/* 拡張鍵クラス */ |
|
|
#define KCLS_DT0 64 |
|
|
#define KCLS_DT1 128 |
|
|
#define KCLS_K2 256 |
|
|
|
|
|
int special = 0; |
|
|
#define ST_ALLN 1 /* 全数 */ |
|
|
#define ST_NIKO 1<<0x1 /* 二構 */ |
|
|
#define ST_BUOO 1<<0x8 /* ぶお */ |
|
|
#define ST_DOSU 1<<0x9 /* 怒数 */ |
|
|
#define ST_CHIN 1<<0xb /* ちん Uni では感嘆用のフラグ */ |
|
|
#define ST_EROI 1<<0xc /* エロ Uni では拡飛のフラグ */ |
|
|
#define ST_HREN 1<<0xd /* 飛連 */ |
|
|
#define ST_YAKU 1<<0xe /* 八雲 */ |
|
|
|
|
|
#ifdef REON |
|
|
#define REGEXPLEN 1024 |
|
|
char regExpStr[REGEXPLEN]; |
|
|
regex_t regExp; |
|
|
#endif /* REON */ |
|
|
|
|
|
void |
|
|
comment( str ) |
|
|
char *str; |
|
|
{ |
|
|
if ( strlen( str ) >= 4 ) { |
|
|
if ( str[1] == '[' && str[3] == ']' ) { |
|
|
switch ( str[2] ) { |
|
|
case '0': special |= ST_ALLN; break; |
|
|
case '1': special |= ST_NIKO; break; |
|
|
case '8': special |= ST_BUOO; break; |
|
|
case '9': special |= (ST_DOSU | ST_ALLN); break; |
|
|
case 'd': special |= ST_HREN; break; |
|
|
case 'e': special |= ST_YAKU; break; |
|
|
case 'Y': special |= ST_CHIN; break; |
|
|
case 'Z': special |= ST_EROI; break; |
|
|
#ifdef KEYLOG |
|
|
case 'K': keyLog = MAKAI_TRUE; break; |
|
|
#endif /* KEYLOG */ |
|
|
case 'S': |
|
|
seedOffset = atoi( str + 4 ); |
|
|
if ( seedOffset < MIN_SOFF || seedOffset > MAX_SOFF ) { |
|
|
fprintf( stderr, "乱数の種のオフセットは、%d 以上 %d 以下で指定してね。\n", MIN_SOFF, MAX_SOFF ); |
|
|
fprintf( stderr, "%d は範囲外なので無視します。\n", seedOffset ); |
|
|
seedOffset = 0; |
|
|
} |
|
|
break; |
|
|
case 'R': |
|
|
#ifdef REON |
|
|
if ( strlen( str ) >= REGEXPLEN ) { |
|
|
fprintf( stderr, "正規表現 (%s) が長すぎ", str ); |
|
|
exit( 1 ); |
|
|
} |
|
|
strcpy( regExpStr, str + 4 ); |
|
|
if ( regcomp( ®Exp, regExpStr, REG_NOSUB|REG_EXTENDED ) != 0 ) { |
|
|
fprintf( stderr, "正規表現 (%s) がおかしい?\n", str ); |
|
|
exit( 1 ); |
|
|
} |
|
|
#else /* REON */ |
|
|
fprintf( stderr, "このバイナリは、正規表現をサポートしていません。\n" ); |
|
|
fprintf( stderr, "%s は無視します。\n", str ); |
|
|
#endif /* REON */ |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
#ifndef ALLKEY |
|
|
/* 指定されたクラスと入っているキーから、classify を行う */ |
|
|
void |
|
|
key_make_map(uint8_t *key, int n) |
|
|
{ |
|
|
int i, j; |
|
|
unsigned c = kcls[n].map[key[n]]; |
|
|
|
|
|
/* 最後の部分は class map を生成する必要ナシ */ |
|
|
/* MAKAI memo |
|
|
6byte 埋めた時の挙動 |
|
|
下の方の if (n == 6) と矛盾 |
|
|
*/ |
|
|
if ( n >= 6 ) return; |
|
|
|
|
|
for ( i = 0; i < 256; i++ ) { |
|
|
unsigned bm = 0; |
|
|
if ( c & KCLS_K1 ) { |
|
|
if ( cp932[256 * key[n] + i] & KCLS_K1 ) { |
|
|
bm |= KCLS_K2 | (cp932[256 * key[n] + i] & KCLS_DT1); |
|
|
} |
|
|
if ( cp932[256 * (key[n] ^ 0x80) + i] & KCLS_K1 ) { |
|
|
bm |= KCLS_K2 | (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_DT1); |
|
|
} |
|
|
} |
|
|
if ( c & (KCLS_AN | KCLS_KA | KCLS_K2) ) { |
|
|
for ( j = 0; j < 256; j++ ) { |
|
|
bm |= cp932[256 * i + j] & (KCLS_AN | KCLS_KA | KCLS_K1 | KCLS_DT0); |
|
|
} |
|
|
} |
|
|
kcls[n + 1].map[i] = bm; |
|
|
if ( i >= 128 && !(n == 0 || n == 1) ) { |
|
|
kcls[n + 1].map[i - 128] |= kcls[n + 1].map[i]; |
|
|
} |
|
|
} |
|
|
|
|
|
if ( n < 6 ) kcls[n + 1].map[0x00] = kcls[n + 1].map[0x80] = 0; |
|
|
#if 0 |
|
|
if ( n == 6 ) kcls[7].map[0x00] |= KCLS_AN; |
|
|
#endif /* 0 */ |
|
|
} |
|
|
#endif /* not ALLKEY */ |
|
|
|
|
|
/* マップから文字を拾ってセット */ |
|
|
unsigned |
|
|
key_set(int n, unsigned ch) |
|
|
{ |
|
|
int cnt = 0, i; |
|
|
|
|
|
#ifdef NOMORE |
|
|
ch %= 256; |
|
|
#endif /* NOMORE */ |
|
|
|
|
|
for ( i = 0; i < 256; i++ ) { |
|
|
if ( kcls[n].map[i] ) { |
|
|
if ( ch-- == 0 ) return i; |
|
|
cnt++; |
|
|
} |
|
|
if ( n != 1 && n != 2 && i >= 127 ) break; |
|
|
} |
|
|
/* 見つからなかったのでもいっぺん */ |
|
|
assert( cnt > 0 ); |
|
|
ch %= cnt; |
|
|
for ( i = 0; i < 256; i++ ) { |
|
|
if ( kcls[n].map[i] ) { |
|
|
if ( ch-- == 0 ) return i; |
|
|
} |
|
|
} |
|
|
assert( !"not matched" ); |
|
|
return 0; |
|
|
} |
|
|
|
|
|
/* bitwise key をセット */ |
|
|
static |
|
|
void |
|
|
key_set64(struct KEY *key64, |
|
|
int n, |
|
|
unsigned k, |
|
|
unsigned vk, |
|
|
unsigned sk) |
|
|
{ |
|
|
int i, j; |
|
|
if (!((vk | sk) & 0x7F)) |
|
|
return; |
|
|
|
|
|
for (i = 0; i < 7; i++) |
|
|
{ |
|
|
if (n == 7 && i < N_STRIDE) continue; |
|
|
if (sk & (1 << i)) |
|
|
{ |
|
|
/* セット */ |
|
|
int o = tr_pc1[n][6 - i] - 1; |
|
|
if (o < 28) |
|
|
{ |
|
|
assert(o >= 0); |
|
|
for (j = 0; j < N_ALU; j++) |
|
|
key64->k[0][0][o].a[j] |
|
|
= key64->k[0][1][o].a[j] |
|
|
= -!!(k & (1 << i)); |
|
|
} |
|
|
else |
|
|
{ |
|
|
assert(o >= 28); |
|
|
assert(o < 56); |
|
|
for (j = 0; j < N_ALU; j++) |
|
|
key64->k[1][0][o - 28].a[j] |
|
|
= key64->k[1][1][o - 28].a[j] |
|
|
= -!!(k & (1 << i)); |
|
|
} |
|
|
} |
|
|
else if (vk & (1 << i)) |
|
|
{ |
|
|
/* 反転 */ |
|
|
int o = tr_pc1[n][6 - i] - 1; |
|
|
if (o < 28) |
|
|
{ |
|
|
assert(o >= 0); |
|
|
for (j = 0; j < N_ALU; j++) |
|
|
key64->k[0][0][o].a[j] |
|
|
= key64->k[0][1][o].a[j] |
|
|
= ~key64->k[0][0][o].a[j]; |
|
|
} |
|
|
else |
|
|
{ |
|
|
assert(o >= 28); |
|
|
assert(o < 56); |
|
|
for (j = 0; j < N_ALU; j++) |
|
|
key64->k[1][0][o - 28].a[j] |
|
|
= key64->k[1][1][o - 28].a[j] |
|
|
= ~key64->k[1][0][o - 28].a[j]; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
/* 指定されたクラスの開始値にリセット |
|
|
直前の文字のクラスに縛られる */ |
|
|
int |
|
|
key_reset(uint8_t *key, int n) |
|
|
{ |
|
|
static char firstCall = 1; |
|
|
|
|
|
if ( firstCall ) { |
|
|
firstCall = 0; |
|
|
} else { |
|
|
if ( umeStr[0] != '\0' && n == 0 ) { |
|
|
exit( 0 ); |
|
|
} |
|
|
} |
|
|
|
|
|
if (n >= 8) |
|
|
return 1; |
|
|
if (n == 7) |
|
|
{ |
|
|
key[7] = 0; |
|
|
return 1; |
|
|
} |
|
|
|
|
|
if ( n >= umeLen ) { |
|
|
#ifdef ALLKEY |
|
|
for ( ; n < 7; n++ ) { |
|
|
key[n] = 1; |
|
|
} |
|
|
key[7] = 0; |
|
|
return 1; |
|
|
#else /* ALLKEY */ |
|
|
key[n] = key_set(n, 0); |
|
|
#endif /* ALLKEY */ |
|
|
} else { |
|
|
if ( umeStr[0] == '\0' ) { |
|
|
#ifdef ALLKEY |
|
|
key[n] = rand() % 0x7f + 1; |
|
|
#else /* ALLKEY */ |
|
|
key[n] = key_set(n, rand()); |
|
|
#endif /* ALLKEY */ |
|
|
} else { |
|
|
key[n] = umeStr[n]; |
|
|
} |
|
|
#ifdef KEYLOG |
|
|
/* 検索空間の記録 */ |
|
|
if ( keyLog && (n == umeLen - 1) ) { |
|
|
FILE *fp; |
|
|
int i; |
|
|
struct timeb tb; |
|
|
struct tm *plt; |
|
|
|
|
|
ftime( &tb ); |
|
|
plt = localtime( &tb.time ); |
|
|
|
|
|
#ifdef OLDDEBUG |
|
|
printf( "\nそぉーるとちぇーんじ!\n" ); |
|
|
#endif /* DEBUG */ |
|
|
if ( (fp = fopen( KEY_LOG_FILE, "at" )) == NULL ) { |
|
|
perror( KEY_LOG_FILE ); |
|
|
exit( 1 ); |
|
|
} |
|
|
for ( i = 0; i < umeLen; i++ ) { |
|
|
fprintf( fp, "%02x", key[i] ); |
|
|
} |
|
|
fprintf( fp, "\t%04d/%02d/%02d %02d:%02d:%02d.%03d\n", |
|
|
plt->tm_year + 1900, plt->tm_mon + 1, plt->tm_mday, |
|
|
plt->tm_hour, plt->tm_min, plt->tm_sec, tb.millitm ); |
|
|
fclose( fp ); |
|
|
} |
|
|
#endif /* KEYLOG */ |
|
|
} |
|
|
|
|
|
#if DEBUG>=3 |
|
|
printf("key[%d]=%02X ncls=%04X\n", n, key[n], kcls[n].map[key[n]]); |
|
|
#endif |
|
|
|
|
|
#ifndef ALLKEY |
|
|
/* セットされた文字を元に、次キャラの文字クラスを決める */ |
|
|
key_make_map(key, n); |
|
|
#endif /* not ALLKEY */ |
|
|
|
|
|
return key_reset(key, n + 1); |
|
|
} |
|
|
|
|
|
/* 指定された鍵空間の中で、キーをひとつ進める |
|
|
安全にインクリメントできた場合 true を返す */ |
|
|
static |
|
|
int |
|
|
key_inc(uint8_t *key, int n) |
|
|
{ |
|
|
#if 0 |
|
|
if ( n != 7 ) { |
|
|
printf( "%d : %02x %02x %02x %02x %02x %02x %02x %02x\n", |
|
|
n, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7] ); |
|
|
} |
|
|
#endif /* 0 */ |
|
|
|
|
|
if ( n >= 8 ) { |
|
|
return 0; |
|
|
} else if ( n == 7 ) { |
|
|
/* MAKAI memo |
|
|
2^N_STRIDE がいっぺんに計算する個数 |
|
|
MMX 6 : 64 個 |
|
|
SSE2 7 : 128 個 |
|
|
このため最後のバイトの進め方が変わる |
|
|
*/ |
|
|
uint8_t o_k = (key[7] + (1 << N_STRIDE)) & 0x7F; |
|
|
if ( !o_k ) { |
|
|
return 0; /* インクリメントできなかったときは次へ進めず待つ */ |
|
|
} else { |
|
|
key[7] = o_k; |
|
|
return 1; |
|
|
} |
|
|
} else if ( key_inc( key, n+1 ) ) { |
|
|
return 1; |
|
|
} |
|
|
|
|
|
/* Salt はインクリメントしない約束にする */ |
|
|
if ( n == 1 || n == 2 ) { |
|
|
return 1; |
|
|
} |
|
|
|
|
|
#ifdef ALLKEY |
|
|
key[n] = ( key[n] & 0x7F ) + 1; |
|
|
if ( key[n] >= 0x80 ) { |
|
|
key[n] = 0xFF; /* 次に突入させないため */ |
|
|
return 0; |
|
|
} |
|
|
key_reset( key, n + 1 ); |
|
|
return 1; |
|
|
#endif /* ALLKEY */ |
|
|
|
|
|
/* 実際に増やしてみる */ |
|
|
assert( n >= 3 ); |
|
|
for ( ;; ) { |
|
|
if (n <= 3 |
|
|
&& !(key[n] & 0x80) |
|
|
&& kcls[n].map[key[n] ^ 0x80] & (KCLS_DT0)) |
|
|
{ |
|
|
/* 半角カタカナの1バイト目 */ |
|
|
key[n] ^= 0x80; |
|
|
} |
|
|
else |
|
|
{ |
|
|
key[n] = (key[n] & 0x7F) + 1; |
|
|
if (key[n] >= 0x80) |
|
|
{ |
|
|
key[n] = 0xFF; /* 次に突入させないため */ |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
if (kcls[n].map[key[n]]) |
|
|
{ |
|
|
#ifndef ALLKEY |
|
|
key_make_map(key, n); |
|
|
#endif /* not ALLKEY */ |
|
|
key_reset(key, n + 1); |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
/* 鍵を完全にリセットする |
|
|
Saltもセットし直す */ |
|
|
static |
|
|
void |
|
|
key_init(uint8_t *key) |
|
|
{ |
|
|
int i, j; |
|
|
|
|
|
key[8] = 0; |
|
|
|
|
|
#ifndef ALLKEY |
|
|
/* 初期マップを組む */ |
|
|
for ( i = 0; i < 256; i++ ) { |
|
|
unsigned bm = 0; |
|
|
|
|
|
for ( j = 0; j < 256; j++ ) { |
|
|
bm |= cp932[256 * i + j]; |
|
|
} |
|
|
kcls[0].map[i] = bm & (KCLS_AN | KCLS_KA | KCLS_K1); |
|
|
if ( i >= 128 ) { |
|
|
kcls[0].map[i - 128] |= kcls[0].map[i]; |
|
|
} |
|
|
} |
|
|
#endif /* not ALLKEY */ |
|
|
|
|
|
key_reset(key, 0); |
|
|
} |
|
|
|
|
|
/*************************************************************** |
|
|
* |
|
|
* 固定キーの生成 |
|
|
* |
|
|
* 一見 Big Endian に非対応のように見えるだろうが |
|
|
* 随所でに散らばっている kludge により |
|
|
* ALU_T が 64 ビットである限り、これで問題なく動く。 |
|
|
* |
|
|
*/ |
|
|
|
|
|
static |
|
|
void |
|
|
key_init_sk(struct KEY *key) |
|
|
{ |
|
|
int i, j; |
|
|
int o; |
|
|
uint64_t m; |
|
|
|
|
|
for (i = 5, m = 0xFFFFFFFF00000000ULL; |
|
|
i >= 0; |
|
|
m ^= (m >> (1 << --i))) |
|
|
{ |
|
|
o = tr_pc1[7][6 - i] - 1; |
|
|
#if DEBUG>=2 |
|
|
printf("%d:%d->%2d: %08X%08X\n", |
|
|
N_Q, i, o, |
|
|
(unsigned)(m >> 32), |
|
|
(unsigned)m); |
|
|
#endif |
|
|
for (j = 0; j < N_Q; j++) |
|
|
if (o < 28) |
|
|
key->k[0][0][o ].q[j] = key->k[0][1][o ].q[j] = m; |
|
|
else |
|
|
key->k[1][0][o - 28].q[j] = key->k[1][1][o - 28].q[j] = m; |
|
|
} |
|
|
#if N_STRIDE==7 |
|
|
/* bit 6 は Little Endian として扱う */ |
|
|
o = 0; |
|
|
assert(tr_pc1[7][0] - 1 == o); |
|
|
assert(N_Q == 2); |
|
|
key->k[0][0][o].q[0] = key->k[0][1][o].q[0] = 0x0000000000000000ULL; |
|
|
key->k[0][0][o].q[1] = key->k[0][1][o].q[1] = 0xFFFFFFFFFFFFFFFFULL; |
|
|
#endif |
|
|
} |
|
|
|
|
|
/*************************************************************** |
|
|
* |
|
|
* Salt のセット |
|
|
* オペランドのオフセットを書き換えて回ってるので注意 |
|
|
* |
|
|
*/ |
|
|
|
|
|
void |
|
|
set_salt(CODE_T *code, |
|
|
struct CRYPT64_DESC const *desc, |
|
|
uint8_t const *k) |
|
|
{ |
|
|
int i, j; |
|
|
|
|
|
static unsigned char *s2c = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; |
|
|
|
|
|
for ( i = 0; i < 2; i++ ) { |
|
|
unsigned s; |
|
|
#ifdef ALLKEY |
|
|
if ( fixedSaltChar[0] != '\0' ) { |
|
|
saltChar[i] = fixedSaltChar[i]; |
|
|
for ( s = 0; s2c[s] != '\0' && s2c[s] != saltChar[i]; s++ ) |
|
|
; |
|
|
assert( s2c[s] != '\0' ); |
|
|
} else { |
|
|
s = rand() % 64; |
|
|
saltChar[i] = s2c[s]; |
|
|
} |
|
|
#else /* ALLKEY */ |
|
|
s = k[1 + i] & 255; |
|
|
if (s > 'z') |
|
|
s = 0; |
|
|
else if (s >= 'a') |
|
|
s = s - 'a' + 2 + 10 + 26; |
|
|
else if (s >= 'A') |
|
|
s = s - 'A' + 2 + 10; |
|
|
else if (s >= '.') |
|
|
s = s - '.'; |
|
|
else |
|
|
s = 0; |
|
|
#ifdef OTAKU |
|
|
{ |
|
|
unsigned s2; |
|
|
do { |
|
|
s2 = rand() % 64; |
|
|
} while ( s == s2 ); |
|
|
s = s2; |
|
|
} |
|
|
#endif /* OTAKU */ |
|
|
saltChar[i] = s2c[s]; |
|
|
#endif /* ALLKEY */ |
|
|
|
|
|
for ( j = 0; j < 6; j++ ) { |
|
|
if ( s & (1 << j) ) { |
|
|
LSALT( desc, code, 0, i, j, 0 ) = sizeof(WS_T) * (((4*i+j+15) & 31) - 16); |
|
|
LSALT( desc, code, 0, i, j, 24 ) = sizeof(WS_T) * (((4*i+j- 1) & 31) - 16); |
|
|
} else { |
|
|
LSALT( desc, code, 0, i, j, 0 ) = sizeof(WS_T) * (((4*i+j- 1) & 31) - 16); |
|
|
LSALT( desc, code, 0, i, j, 24 ) = sizeof(WS_T) * (((4*i+j+15) & 31) - 16); |
|
|
} |
|
|
LSALT( desc, code, 0, i, j, 12 ) = sizeof(WS_T) * (((4*i+j+ 7) & 31) - 16); |
|
|
LSALT( desc, code, 0, i, j, 36 ) = sizeof(WS_T) * (((4*i+j+23) & 31) - 16); |
|
|
} |
|
|
} |
|
|
} |
|
| 49 |
|
|
| 50 |
#define USEC_SEC 1000 /* 1秒 */ |
#define USEC_SEC 1000 /* 1秒 */ |
| 51 |
|
|
| 70 |
return (uint64_t)USEC_SEC * sec + msec; |
return (uint64_t)USEC_SEC * sec + msec; |
| 71 |
} |
} |
| 72 |
|
|
|
static |
|
|
int |
|
|
log_printf(FILE *ofp, char const *fmt, ...) |
|
|
{ |
|
|
int r; |
|
|
va_list ap; |
|
|
va_start(ap, fmt); |
|
|
|
|
|
if ( ofp != nfp ) { |
|
|
vfprintf(stdout, fmt, ap); |
|
|
} |
|
|
|
|
|
r = vfprintf(ofp, fmt, ap); |
|
|
va_end(ap); |
|
|
#ifdef HITEXIT |
|
|
exit( 0 ); |
|
|
#endif /* HITEXIT */ |
|
|
if (r > 0) |
|
|
return r; |
|
|
perror("log_printf"); |
|
|
exit(errno); |
|
|
} |
|
|
|
|
|
static |
|
|
void |
|
|
hit( fp, hash, key, kk, k, kind, dotrans ) |
|
|
FILE *fp; |
|
|
char *hash; |
|
|
uint8_t *key; |
|
|
int kk; |
|
|
int k; |
|
|
unsigned char *kind; |
|
|
int dotrans; |
|
|
{ |
|
|
struct timeb tb; |
|
|
struct tm *plt; |
|
|
int namaKey; |
|
|
uint8_t buf[32]; |
|
|
|
|
|
ftime( &tb ); |
|
|
plt = localtime( &tb.time ); |
|
|
|
|
|
memcpy( buf, key, 8 ); |
|
|
buf[8] = buf[9] = 0; |
|
|
buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k; |
|
|
|
|
|
namaKey = MAKAI_TRUE; |
|
|
#ifndef NAMA |
|
|
if ( dotrans ) { |
|
|
if ( translate( buf, 0, 1 ) ) { |
|
|
namaKey = MAKAI_FALSE; |
|
|
} |
|
|
} |
|
|
#endif /* NAMA */ |
|
|
|
|
|
if ( namaKey ) { |
|
|
log_printf( fp, "◆%s ##%02x%02x%02x%02x%02x%02x%02x%02x%c%c" |
|
|
"\t%04d/%02d/%02d %02d:%02d:%02d.%03d" |
|
|
" %s 生\n", |
|
|
hash, |
|
|
buf[0], buf[1], buf[2], buf[3], |
|
|
buf[4], buf[5], buf[6], buf[7], |
|
|
saltChar[0], saltChar[1], |
|
|
plt->tm_year + 1900, plt->tm_mon + 1, plt->tm_mday, |
|
|
plt->tm_hour, plt->tm_min, plt->tm_sec, tb.millitm, |
|
|
kind ); |
|
|
} else { |
|
|
log_printf( fp, "◆%s #%s" |
|
|
"\t%04d/%02d/%02d %02d:%02d:%02d.%03d" |
|
|
"\t(%02X %02X %02X %02X %02X %02X %02X %02X/%02X)" |
|
|
" %s\n", |
|
|
hash, |
|
|
buf, |
|
|
plt->tm_year + 1900, plt->tm_mon + 1, plt->tm_mday, |
|
|
plt->tm_hour, plt->tm_min, plt->tm_sec, tb.millitm, |
|
|
buf[0], buf[1], buf[2], buf[3], buf[4], |
|
|
buf[5], buf[6], buf[7], buf[8], |
|
|
kind ); |
|
|
} |
|
|
} |
|
|
|
|
| 73 |
/*************************************************************** |
/*************************************************************** |
| 74 |
* |
* |
| 75 |
* CPU capabilities を取得 |
* CPU capabilities を取得 |
| 180 |
* |
* |
| 181 |
*/ |
*/ |
| 182 |
|
|
|
#define NQ_CRYPT 64 |
|
|
#define NQ_CMP 32 |
|
|
|
|
| 183 |
#if defined(__GNUC__) |
#if defined(__GNUC__) |
| 184 |
|
|
| 185 |
typedef int32_t ATOMWORD_T; |
typedef int32_t ATOMWORD_T; |
| 230 |
#define THREAD_INFINITE INFINITE |
#define THREAD_INFINITE INFINITE |
| 231 |
|
|
| 232 |
typedef HANDLE THREAD_TH_T; |
typedef HANDLE THREAD_TH_T; |
|
typedef HANDLE THREAD_EV_T; |
|
| 233 |
|
|
| 234 |
#define thread_sleep(n) Sleep(n) |
#define thread_sleep(n) Sleep(n) |
| 235 |
#define thread_create(th, proc, arg) {(th) = (HANDLE)_beginthread(proc, 8192, arg);} |
#define thread_create(th, proc, arg) {(th) = (HANDLE)_beginthread(proc, 8192, arg);} |
|
#define thread_create_event(ev, f) {(ev) = CreateEvent(NULL, TRUE, f, NULL);} |
|
|
#define thread_signal_event(ev) SetEvent(ev) |
|
|
#define thread_clear_event(ev) ResetEvent(ev) |
|
| 236 |
#define thread_get_tid() GetCurrentThread() |
#define thread_get_tid() GetCurrentThread() |
| 237 |
#define thread_set_priority(tid,n) SetThreadPriority(tid, n) |
#define thread_set_priority(tid,n) SetThreadPriority(tid, n) |
|
#if 0 |
|
|
#undef thread_set_priority |
|
|
#endif |
|
| 238 |
#define thread_set_affinity(tid,m) SetThreadAffinityMask(tid, (DWORD_PTR)1 << (m)) |
#define thread_set_affinity(tid,m) SetThreadAffinityMask(tid, (DWORD_PTR)1 << (m)) |
| 239 |
|
|
| 240 |
static |
#elif defined(_POSIX_SOURCE) |
|
int |
|
|
thread_wait_event(THREAD_EV_T ev, DWORD tmo) |
|
|
{ |
|
|
DWORD r = WaitForSingleObject(ev, tmo); |
|
|
return (r < 0 |
|
|
? r |
|
|
: (r == WAIT_TIMEOUT |
|
|
? -1 |
|
|
: r)); |
|
|
} |
|
|
|
|
|
#elif defined(_POSIX_SOURCE) || defined(__FreeBSD__) |
|
| 241 |
|
|
| 242 |
#include <pthread.h> |
#include <pthread.h> |
| 243 |
#include <unistd.h> |
#include <unistd.h> |
| 255 |
#define THREAD_PRIORITY_IDLE 16 |
#define THREAD_PRIORITY_IDLE 16 |
| 256 |
|
|
| 257 |
typedef pthread_t THREAD_TH_T; |
typedef pthread_t THREAD_TH_T; |
|
typedef struct |
|
|
{ |
|
|
pthread_mutex_t m; |
|
|
pthread_cond_t c; |
|
|
int volatile f; |
|
|
} THREAD_EV_T; |
|
| 258 |
|
|
| 259 |
#define thread_sleep(n) (usleep(1000 * (n)) != EINVAL || sleep((n) / 1000)) |
#define thread_sleep(n) (usleep(1000 * (n)) != EINVAL || sleep((n) / 1000)) |
| 260 |
#define thread_create(th, proc, arg) thread_create_p(&(th), proc, arg) |
#define thread_create(th, proc, arg) thread_create_p(&(th), proc, arg) |
|
#define thread_create_event(ev, f) thread_create_event_p(&(ev), f) |
|
|
#define thread_signal_event(ev) thread_set_event_p(&(ev), 1) |
|
|
#define thread_clear_event(ev) thread_set_event_p(&(ev), 0) |
|
|
#define thread_wait_event(ev,tmo) thread_wait_event_p(&(ev), tmo) |
|
| 261 |
|
|
| 262 |
static |
static |
| 263 |
void |
void |
| 266 |
pthread_create(th, NULL, (void *(*)(void *))proc, param); |
pthread_create(th, NULL, (void *(*)(void *))proc, param); |
| 267 |
} |
} |
| 268 |
|
|
|
static |
|
|
void |
|
|
thread_create_event_p(THREAD_EV_T *ev, int f) |
|
|
{ |
|
|
ev->f = f; |
|
|
pthread_cond_init(&ev->c, NULL); |
|
|
pthread_mutex_init(&ev->m, NULL); |
|
|
} |
|
|
|
|
|
static |
|
|
void |
|
|
thread_set_event_p(THREAD_EV_T *ev, int f) |
|
|
{ |
|
|
pthread_mutex_lock(&ev->m); |
|
|
if (ev->f != f) |
|
|
{ |
|
|
ev->f = f; |
|
|
pthread_cond_broadcast(&ev->c); |
|
|
} |
|
|
pthread_mutex_unlock(&ev->m); |
|
|
} |
|
|
|
|
|
static |
|
|
int |
|
|
thread_wait_event_p(THREAD_EV_T *ev, int a_tmo) |
|
|
{ |
|
|
int timeout = a_tmo; |
|
|
struct timeval now; |
|
|
struct timespec tmo; |
|
|
int r; |
|
|
|
|
|
pthread_mutex_lock(&ev->m); |
|
|
|
|
|
/* 現在時刻からタイムアウト時刻を求める |
|
|
めんどくせー */ |
|
|
gettimeofday(&now, NULL); |
|
|
tmo.tv_sec = now.tv_sec + (timeout / 1000); |
|
|
timeout %= 1000; |
|
|
timeout *= 1000; |
|
|
if (now.tv_usec >= 1000000 - timeout) |
|
|
{ |
|
|
timeout -= 1000000; |
|
|
tmo.tv_sec++; |
|
|
} |
|
|
tmo.tv_nsec = 1000 * (now.tv_usec + timeout); |
|
|
r = 0; |
|
|
while (!ev->f) |
|
|
{ |
|
|
r = pthread_cond_timedwait(&ev->c, &ev->m, &tmo); |
|
|
if (r == ETIMEDOUT |
|
|
&& a_tmo < THREAD_INFINITE) |
|
|
break; |
|
|
} |
|
|
|
|
|
pthread_mutex_unlock(&ev->m); |
|
|
|
|
|
return (r == ETIMEDOUT |
|
|
? (ETIMEDOUT < 0 ? ETIMEDOUT : -1) |
|
|
: 0); |
|
|
} |
|
|
|
|
| 269 |
#if defined(__linux__) |
#if defined(__linux__) |
| 270 |
|
|
| 271 |
/* デフォルトスケジューリングポリシーでは |
/* デフォルトスケジューリングポリシーでは |
| 300 |
{ |
{ |
| 301 |
/* 以下は共通情報のコピー */ |
/* 以下は共通情報のコピー */ |
| 302 |
CODE_T *code; |
CODE_T *code; |
| 303 |
THREAD_EV_T *p_ev_ks_activated; |
off_t code_cmp; |
| 304 |
ATOMWORD_T volatile *p_nidle; /* 待ちに入ったら増加 */ |
unsigned seed; |
| 305 |
|
|
| 306 |
/* 以下はスレッド固有 */ |
/* 以下はスレッド固有 */ |
| 307 |
#ifdef thread_set_priority |
#ifdef thread_set_priority |
|
THREAD_TH_T th; |
|
| 308 |
int pri; |
int pri; |
| 309 |
#endif |
#endif |
| 310 |
}; |
}; |
| 311 |
|
|
| 312 |
static |
static |
|
volatile ATOMWORD_T wp_crypt, rp_crypt; |
|
|
static |
|
|
struct PACKET_CRYPT64 *volatile q_crypt[NQ_CRYPT]; |
|
|
|
|
|
static |
|
|
volatile ATOMWORD_T wp_cmp, rp_cmp; |
|
|
static |
|
|
struct PACKET_CRYPT64 *volatile q_cmp[NQ_CMP]; |
|
|
|
|
|
static |
|
| 313 |
uint64_t |
uint64_t |
| 314 |
thread_avail(void) |
thread_avail(void) |
| 315 |
{ |
{ |
| 331 |
(unsigned)mask, |
(unsigned)mask, |
| 332 |
(unsigned)mask_s); |
(unsigned)mask_s); |
| 333 |
#endif |
#endif |
|
/* todo WIN32 でないときの n 倍表示 */ |
|
| 334 |
if (popcnt64(mask_s) == 1) |
if (popcnt64(mask_s) == 1) |
| 335 |
/* 何も言うまい */; |
/* 何も言うまい */; |
| 336 |
else if (mask == mask_s) |
else if (mask == mask_s) |
| 356 |
m |= 1ULL << i; |
m |= 1ULL << i; |
| 357 |
|
|
| 358 |
return m; |
return m; |
|
|
|
|
#elif defined( __FreeBSD__ ) |
|
|
|
|
|
#include <sys/sysctl.h> |
|
|
|
|
|
int i; |
|
|
uint64_t m; |
|
|
int nCPU; |
|
|
int mib[2]; |
|
|
size_t len; |
|
|
|
|
|
mib[0] = CTL_HW; |
|
|
mib[1] = HW_NCPU; |
|
|
len = sizeof( nCPU ); |
|
|
sysctl( mib, 2, &nCPU, &len, NULL, 0 ); |
|
|
m = (1ULL << nCPU) - 1; |
|
|
|
|
|
return m; |
|
|
|
|
|
#elif defined( __sun__ ) |
|
|
|
|
|
#include <sys/unistd.h> |
|
|
#include <sys/processor.h> |
|
|
|
|
|
uint64_t m; |
|
|
processorid_t i, cpuid_max; |
|
|
|
|
|
m = 0; |
|
|
cpuid_max = sysconf( _SC_CPUID_MAX ); |
|
|
for ( i = 0; i <= cpuid_max; i++ ) { |
|
|
if ( p_online( i, P_STATUS ) == P_ONLINE ) { |
|
|
m |= 1ULL << i; |
|
|
} |
|
|
} |
|
|
|
|
|
return m; |
|
|
|
|
| 359 |
#else |
#else |
| 360 |
|
|
| 361 |
/* XXX プロセッサ数を調べ上げてください */ |
/* XXX プロセッサ数を調べ上げてください */ |
| 366 |
|
|
| 367 |
static |
static |
| 368 |
NORETURN |
NORETURN |
| 369 |
thread_crypt64(void *a_param) |
thread_crypt64_new(void *a_param) |
| 370 |
{ |
{ |
| 371 |
struct THREAD_PARAM *param = a_param; |
struct THREAD_PARAM *param = a_param; |
| 372 |
CODE_T *code = param->code; |
CODE_T *code = param->code; |
| 373 |
struct PACKET_CRYPT64 *pkt; |
CODE_T *cmp = code + param->code_cmp; |
| 374 |
#ifdef thread_set_priority |
struct KS_KEY key; |
| 375 |
THREAD_TH_T th = thread_get_tid(); |
struct PACKET_CRYPT64 *pkt = packet_create(16, 1024, key.key); |
| 376 |
thread_set_priority(th, param->pri); |
uint64_t *ploop; |
| 377 |
#endif |
THREAD_TH_T th = thread_get_tid(); |
| 378 |
|
|
| 379 |
for(;;) |
WaitForSingleObject(mutex_key, INFINITE); |
| 380 |
{ |
|
| 381 |
ATOMWORD_T rp; |
ploop = &loop_cpu[n_cpus++]; |
| 382 |
ATOMWORD_T wp; |
|
| 383 |
|
srand(usec() ^ param->seed ^ (unsigned)th); |
| 384 |
|
key_init(&key); |
| 385 |
|
ReleaseMutex(mutex_key); |
| 386 |
|
|
|
/* キューから要求を取り出す */ |
|
|
for (;;) |
|
|
{ |
|
|
while ((rp = rp_crypt, |
|
|
WRAP(wp_crypt, NQ_CRYPT) == WRAP(rp, NQ_CRYPT) |
|
|
/*|| q_crypt[WRAP(rp, NQ_CRYPT)] == NULL*/)) |
|
|
{ |
|
|
THREAD_TIMEOUT_T tmo = (WRAP(wp_crypt, NQ_CRYPT) == WRAP(rp, NQ_CRYPT) |
|
|
? THREAD_INFINITE |
|
|
: 1); |
|
|
int r; |
|
|
|
|
|
/* 寝た */ |
|
|
if (tmo == THREAD_INFINITE) |
|
|
{ |
|
|
LOCK_INC(param->p_nidle); |
|
|
} |
|
|
|
|
|
/* 要求待ち */ |
|
|
r = thread_wait_event(*param->p_ev_ks_activated, tmo); |
|
|
|
|
|
if (tmo == THREAD_INFINITE) |
|
|
{ |
|
|
/* 起こされた */ |
|
|
LOCK_DEC(param->p_nidle); |
|
|
} |
|
|
else if (r >= 0) |
|
|
{ |
|
|
/* もうちょっと寝てみる */ |
|
|
thread_sleep(tmo); |
|
|
} |
|
|
|
|
|
/* 自らの優先度を戻す |
|
|
(外からブーストされてるかも) */ |
|
| 387 |
#ifdef thread_set_priority |
#ifdef thread_set_priority |
| 388 |
if (r >= 0) |
thread_set_priority(th, param->pri); |
|
thread_set_priority(th, param->pri); |
|
| 389 |
#endif |
#endif |
|
} |
|
|
|
|
|
if (LOCK_CAS(&rp_crypt, rp + 1, rp) != rp) |
|
|
continue; |
|
|
rp = WRAP(rp, NQ_CRYPT); |
|
|
break; |
|
|
} |
|
|
|
|
|
pkt = q_crypt[rp]; |
|
|
assert(pkt != NULL); |
|
|
pkt = LOCK_CASP(&q_crypt[rp], NULL, pkt); |
|
|
assert(pkt != NULL); |
|
|
|
|
|
/* 実行してみる */ |
|
|
CALL_CRYPT64(code, &pkt->key64, &pkt->param64); |
|
| 390 |
|
|
| 391 |
/* 結果をキューにたたき込む */ |
for (;;) |
| 392 |
for (;;) |
{ |
| 393 |
|
do |
| 394 |
{ |
{ |
| 395 |
while ((wp = wp_cmp, |
int j; |
| 396 |
WRAP(rp_cmp - 1, NQ_CMP) == WRAP(wp, NQ_CMP)) |
for (j = 0; j < 8; j++) |
|
|| q_cmp[WRAP(wp, NQ_CMP)] != NULL) |
|
| 397 |
{ |
{ |
| 398 |
#if DEBUG>=1 |
key_set64(&pkt->key64, j, key.key[j], key.key[j] ^ pkt->uk.key[j], 0); |
| 399 |
fprintf(stderr, |
pkt->uk.key[j] = key.key[j]; |
|
"q_cmp stalled(%d,%d) %p\n", |
|
|
(unsigned)WRAP(wp, NQ_CMP), |
|
|
(unsigned)WRAP(rp_cmp - 1, NQ_CMP), |
|
|
q_cmp[WRAP(wp, NQ_CMP)]); |
|
|
#endif |
|
|
thread_sleep(1); |
|
| 400 |
} |
} |
| 401 |
|
CALL_CRYPT64(code, |
| 402 |
if (LOCK_CAS(&wp_cmp, wp + 1, wp) != wp) |
&pkt->key64, |
| 403 |
continue; |
&pkt->param64); |
| 404 |
wp = WRAP(wp, NQ_CMP); |
CALL_CMP64(cmp, |
| 405 |
break; |
pkt->param64.hit, |
| 406 |
|
pkt->param64.lr); |
| 407 |
|
check_hit(pkt, pkt->param64.hit); |
| 408 |
|
*ploop += N_ALU * ALU_BITS; |
| 409 |
} |
} |
| 410 |
|
while (key_inc(&key, 6, 8) || key_inc(&key, KEY_SHUFFLE_POS, 8)); |
| 411 |
|
|
| 412 |
pkt = LOCK_CASP(&q_cmp[wp], pkt, NULL); |
WaitForSingleObject(mutex_key, INFINITE); |
| 413 |
assert(pkt == NULL); |
key_reset(&key, 0); |
| 414 |
|
ReleaseMutex(mutex_key); |
| 415 |
} |
} |
|
} |
|
|
|
|
|
char |
|
|
*bname( char *path ) |
|
|
{ |
|
|
char *p; |
|
| 416 |
|
|
| 417 |
#ifdef OLDEBUG |
/* notreached */ |
|
printf( "path <%s>\n", path ); |
|
|
#endif /* DEBUG */ |
|
|
|
|
|
for ( p = path; *p != '\0'; p++ ) |
|
|
; |
|
|
while ( *p != '/' && *p != '\\' && p != path ) { |
|
|
if ( *p == '.' ) { |
|
|
*p = '\0'; |
|
|
} |
|
|
p--; |
|
|
} |
|
|
if ( p != path ) { |
|
|
p++; |
|
|
} |
|
|
|
|
|
#ifdef OLDEBUG |
|
|
printf( "p <%s>\n", p ); |
|
|
#endif /* DEBUG */ |
|
|
|
|
|
return( p ); |
|
|
} |
|
|
|
|
|
void |
|
|
usage( path ) |
|
|
char *path; |
|
|
{ |
|
|
char *myName; |
|
|
|
|
|
myName = bname( path ); |
|
|
#ifdef ALLKEY |
|
|
printf( "%s [-t num] [-m mask] [-s num] [-g num] [-k salt] [-v] [\"str\"]\n", myName ); |
|
|
#else /* ALLKEY */ |
|
|
printf( "%s [-t num] [-m mask] [-s num] [-g num] [-v] [\"str\"]\n", myName ); |
|
|
#endif /* ALLKEY */ |
|
|
printf( " -t num : 検索スレッド数 ( %d ≦ num ≦ %d )\n", |
|
|
MIN_THREAD, MAX_THREAD ); |
|
|
printf( " -m mask : 実行する CPU を指定するマスク ( 1 ビット ≦ mask のビット数 ≦ %d ビット )\n", |
|
|
MAX_THREAD ); |
|
|
printf( " -s num : 乱数の種 ( 1 ≦ num ≦ %u )\n", UINT_MAX ); |
|
|
printf( " -g num : がんばりぐあい ( %d (やる気なし) ≦ num ≦ %d (フルパワー), デフォルトは、%d )\n", MIN_GEAR, MAX_GEAR, DEF_GEAR ); |
|
|
#ifdef ALLKEY |
|
|
printf( " -k salt : 塩を指定\n" ); |
|
|
#endif /* ALLKEY */ |
|
|
printf( " -v : 冗長メッセージ\n" ); |
|
|
printf( " str : 先頭に埋め込む文字列 ( %d ≦ str のバイト数 ≦ %d )\n", |
|
|
MIN_UME, MAX_UME ); |
|
|
} |
|
|
|
|
|
/* ヒット時には出力ファイルへのポインタを返す */ |
|
|
FILE * |
|
|
checkSpecial( trip, kind ) |
|
|
char *trip; |
|
|
unsigned char *kind; |
|
|
{ |
|
|
if ( special & ST_CHIN ) { |
|
|
/* ^Chi(r */ |
|
|
if ( trip[0] == 'C' && trip[1] == 'h' && trip[2] == 'i' && |
|
|
trip[3] == 'n' && trip[4] == 'k' && trip[5] == 'o' ) { |
|
|
strcpy( kind, "ち" ); |
|
|
return( cfp ); |
|
|
} |
|
|
} |
|
|
|
|
|
if ( special & ST_BUOO ) { |
|
|
/* ぶお [A-Za-z]aoo[A-Za-z]uoo$ */ |
|
|
if ( trip[3] == 'a' && trip[4] == 'o' && trip[5] == 'o' && |
|
|
trip[7] == 'u' && trip[8] == 'o' && trip[9] == 'o' && |
|
|
isalpha( trip[2] ) && isalpha( trip[6] ) ) { |
|
|
strcpy( kind, "ぶ" ); |
|
|
return( tfp ); |
|
|
} |
|
|
} |
|
|
|
|
|
if ( special & ST_EROI ) { |
|
|
int i; |
|
|
/* エロい人型二構 その 1 looooloooo */ |
|
|
if ( trip[0] == trip[5] && |
|
|
trip[1] == trip[2] && trip[1] == trip[3] && trip[1] == trip[4] && |
|
|
trip[1] == trip[6] && trip[1] == trip[7] && trip[1] == trip[8] && |
|
|
trip[1] == trip[9] ) { |
|
|
strcpy( kind, "エ" ); |
|
|
return( tfp ); |
|
|
} |
|
|
/* エロい人型二構 その 2 [./] */ |
|
|
for ( i = 0; i < TRIP_LEN; i++ ) { |
|
|
if ( trip[i] != '.' && trip[i] != '/' ) { |
|
|
goto NOEROI; |
|
|
} |
|
|
} |
|
|
strcpy( kind, "エ" ); |
|
|
return( tfp ); |
|
|
} |
|
|
NOEROI: |
|
|
|
|
|
if ( special & ST_NIKO ) { |
|
|
/* 二構 */ |
|
|
int i; |
|
|
char ch1, ch2; |
|
|
ch1 = trip[0]; |
|
|
for ( i = 1; i < TRIP_LEN; i++ ) { |
|
|
if ( trip[i] != ch1 ) break; |
|
|
} |
|
|
ch2 = trip[i]; |
|
|
for ( ; i < TRIP_LEN; i++ ) { |
|
|
if ( trip[i] != ch1 && trip[i] != ch2 ) goto NONIKO; |
|
|
} |
|
|
strcpy( kind, "二" ); |
|
|
return( tfp ); |
|
|
} |
|
|
NONIKO: |
|
|
|
|
|
if ( special & ST_YAKU ) { |
|
|
/* 八雲 */ |
|
|
if ( trip[0] == trip[1] && trip[0] == trip[2] && |
|
|
trip[3] == trip[4] && trip[3] == trip[5] && |
|
|
trip[6] == trip[7] && trip[6] == trip[8] && trip[9] == '.' ) { |
|
|
strcpy( kind, "八" ); |
|
|
return( tfp ); |
|
|
} |
|
|
} |
|
|
|
|
|
/* 飛連関連のコードは、セロリン ◆Celeron/rc 作 */ |
|
|
if ( special & ST_HREN ) { |
|
|
/* 飛連 */ |
|
|
int w, x = 0, y = 0; |
|
|
for ( w = 0; w < TRIP_LEN; w++ ) { |
|
|
if ( trip[w] == trip[0] ) x += 1; |
|
|
if ( trip[w] == trip[1] ) y += 1; |
|
|
if ( x >= 8 || y >= 8 ) { |
|
|
strcpy( kind, "飛" ); |
|
|
return( tfp ); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
if ( special & ST_ALLN ) { |
|
|
/* 全数 か 怒数 */ |
|
|
if ( isdigit( trip[0] ) && isdigit( trip[1] ) && isdigit( trip[2] ) && |
|
|
isdigit( trip[3] ) && isdigit( trip[4] ) && isdigit( trip[5] ) && |
|
|
isdigit( trip[6] ) && isdigit( trip[7] ) && isdigit( trip[8] ) && |
|
|
isdigit( trip[9] ) ) { |
|
|
if ( special & ST_DOSU ) { |
|
|
/* 全数 & 回文 */ |
|
|
if ( trip[0] == trip[9] && trip[1] == trip[8] && trip[2] == trip[7] && |
|
|
trip[3] == trip[6] && trip[4] == trip[5] ) { |
|
|
strcpy( kind, "怒" ); |
|
|
return( tfp ); |
|
|
} |
|
|
/* 全数 & 双連 */ |
|
|
if ( trip[0] == trip[1] && trip[2] == trip[3] && trip[4] == trip[5] && |
|
|
trip[6] == trip[7] && trip[8] == trip[9] ) { |
|
|
strcpy( kind, "怒" ); |
|
|
return( tfp ); |
|
|
} |
|
|
/* 全数 & 山彦 */ |
|
|
if ( trip[0] == trip[5] && trip[1] == trip[6] && trip[2] == trip[7] && |
|
|
trip[3] == trip[8] && trip[4] == trip[9] ) { |
|
|
strcpy( kind, "怒" ); |
|
|
return( tfp ); |
|
|
} |
|
|
/* 最大と最小は、純 8 連で出るので削除 */ |
|
|
} else { |
|
|
strcpy( kind, "数" ); |
|
|
return( nfp ); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
return( NULL ); |
|
| 418 |
} |
} |
| 419 |
|
|
| 420 |
/*************************************************************** |
/*************************************************************** |
| 428 |
{ |
{ |
| 429 |
int i; |
int i; |
| 430 |
int mincnt; |
int mincnt; |
|
int nblk_hit, nblk_total; |
|
|
int nap_hit, nap_total; |
|
| 431 |
CODE_T *code = NULL; |
CODE_T *code = NULL; |
| 432 |
off_t code_cmp; |
off_t code_cmp; |
|
FILE *ofp; |
|
| 433 |
FILE *sfp; /* scoreboard */ |
FILE *sfp; /* scoreboard */ |
| 434 |
struct ITREE *root_expr; |
struct ITREE *root_expr; |
| 435 |
uint64_t proc_mask; |
uint64_t proc_mask; |
|
int ks_activated; |
|
|
static THREAD_EV_T event_ks_activated; |
|
|
static ATOMWORD_T volatile nidle; |
|
| 436 |
struct THREAD_PARAM *threads = NULL; |
struct THREAD_PARAM *threads = NULL; |
| 437 |
int nthreads; |
int nthreads; |
|
int npkts; |
|
|
struct PACKET_CRYPT64 *pkts, *pkt_hit; |
|
|
uint64_t pkts_vacant; |
|
| 438 |
int tn; |
int tn; |
| 439 |
int cr; |
int cr; |
| 440 |
|
|
| 441 |
/* 鍵文字列 */ |
/* 鍵文字列 */ |
| 442 |
uint8_t key[8 + 8]; |
struct KS_KEY key; |
|
|
|
|
int xhash_loaded; |
|
|
|
|
|
#if defined(WIN32) |
|
|
#define YOUSUMI 6 |
|
|
int maxSpeed; /* 一秒間に検索した個数の最大値 (YOUSUMI 回計測中) */ |
|
|
int sCnt; /* 速度を表示した回数 */ |
|
|
int lCntMax; /* Sleep() のためのループ最大値 */ |
|
|
int lCnt; /* Sleep() のためのループカウンタ */ |
|
|
#endif /* WIN32 */ |
|
| 443 |
|
|
| 444 |
#define UPDATE_INTERVAL 8 /* 速度表示の間隔 秒 */ |
#define UPDATE_INTERVAL 8 /* 速度表示の間隔 秒 */ |
| 445 |
struct status { |
struct status { |
| 450 |
} status; |
} status; |
| 451 |
uint64_t curTime; |
uint64_t curTime; |
| 452 |
uint32_t upd_int = 0; |
uint32_t upd_int = 0; |
| 453 |
|
/* |
| 454 |
|
平均速度 (trips/s) * UPDATE_INTERVAL が UINT32_MAX を超えると発狂する。 |
| 455 |
|
UINT32_MAX = 4294967295, 平均速度 = 100Mtrips/s なら、 |
| 456 |
|
4294967295 / (100 * 1000 * 1000) = 42.949 秒まで。(和良 |
| 457 |
|
LOOP_FACTOR が平均速度より十分小さければ、ほぼ指定間隔になる。 |
| 458 |
|
LOOP_FACTOR * UINT32_MAX + LOOP_FACOTR 個検索するとオーバーフローする。w |
| 459 |
|
*/ |
| 460 |
|
|
| 461 |
#if defined(WIN32) |
if (!cpuid_issupported()) |
| 462 |
SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS ); |
{ |
| 463 |
maxSpeed = 0; |
fprintf(stderr, "この環境で走らせることが想定されていません。\n"); |
| 464 |
sCnt = 0; |
exit(1); |
| 465 |
lCntMax = 0; |
} |
|
lCnt = 0; |
|
|
#endif |
|
| 466 |
|
|
| 467 |
{ |
assert((1 << N_STRIDE) == N_ALU * ALU_BITS); |
|
int optChar; |
|
|
extern char *optarg; |
|
|
extern int optind; |
|
|
char *chPtr; |
|
|
|
|
|
nThread = 0; |
|
|
pmask = 0; |
|
|
seed = 0; |
|
|
seedOffset = 0; /* コマンドラインオプションではないが、ここで初期化 */ |
|
|
verbose = 0; |
|
|
gear = DEF_GEAR; |
|
|
#ifdef ALLKEY |
|
|
fixedSaltChar[0] = '\0'; |
|
|
while ( (optChar = getopt(argc, argv, "t:m:s:g:k:vh")) != EOF ) { |
|
|
#else /* ALLKEY */ |
|
|
while ( (optChar = getopt(argc, argv, "t:m:s:g:vh")) != EOF ) { |
|
|
#endif /* ALLKEY */ |
|
|
switch ( optChar ) { |
|
|
case 't': |
|
|
nThread = atoi( optarg ); |
|
|
if ( nThread < MIN_THREAD || nThread > MAX_THREAD ) { |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
} |
|
|
break; |
|
|
case 'm': |
|
|
if ( strlen( optarg ) > MAX_THREAD ) { |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
} |
|
|
for ( chPtr = optarg; *chPtr != '\0'; chPtr++ ) { |
|
|
pmask <<= 1; |
|
|
switch ( *chPtr ) { |
|
|
case '0': |
|
|
/* なにもしない */ |
|
|
break; |
|
|
case '1': |
|
|
pmask |= 1; |
|
|
break; |
|
|
default: |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
break; |
|
|
} |
|
|
} |
|
|
if ( pmask < MIN_THREAD ) { |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
} |
|
|
break; |
|
|
case 's': |
|
|
if ( optarg[0] == '-' ) { |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
} |
|
|
seed = (unsigned int)atoi( optarg ); |
|
|
if ( seed < 1 || seed > UINT_MAX ) { |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
} |
|
|
break; |
|
|
case 'g': |
|
|
gear = atoi( optarg ); |
|
|
if ( gear < MIN_GEAR || gear > MAX_GEAR ) { |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
} |
|
|
break; |
|
|
#ifdef ALLKEY |
|
|
case 'k': |
|
|
if ( strlen( optarg ) != 2 ) { |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
} |
|
|
for ( i = 0; i < 2; i++ ) { |
|
|
if ( !isdigit( optarg[i] ) && !isalpha( optarg[i] ) && |
|
|
optarg[i] != '.' && optarg[i] != '/' ) { |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
} |
|
|
fixedSaltChar[i] = optarg[i]; |
|
|
} |
|
|
break; |
|
|
#endif /* ALLKEY */ |
|
|
case 'v': |
|
|
verbose = 1; |
|
|
break; |
|
|
case 'h': |
|
|
usage( argv[0] ); |
|
|
exit( 0 ); |
|
|
break; |
|
|
default: |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
} |
|
|
} |
|
|
|
|
|
switch ( argc - optind ) { |
|
|
case 0: |
|
|
umeStr[0] = '\0'; |
|
|
umeLen = KEY_SHUFFLE_POS; |
|
|
break; |
|
|
case 1: |
|
|
strcpy( umeStr, argv[optind] ); |
|
|
umeLen = strlen( umeStr ); |
|
|
if ( umeLen < MIN_UME || umeLen > MAX_UME ) { |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
} |
|
|
break; |
|
|
default: |
|
|
usage( argv[0] ); |
|
|
exit( 1 ); |
|
|
} |
|
|
} |
|
|
#ifdef REON |
|
|
regExpStr[0] = '\0'; |
|
|
#endif /* REON */ |
|
|
|
|
|
#ifdef NAMA |
|
|
fprintf(stderr, "生キーバージョン\n"); |
|
|
fprintf(stderr, "万が一、トリップが化けた場合、\n"); |
|
|
fprintf(stderr, "http://trip.is-a-geek.net/test/read.cgi/ra8bbs/1217089930/\n"); |
|
|
fprintf(stderr, "に報告すると次のバージョンで改善されるかも。\n\n"); |
|
|
#endif /* NAMA */ |
|
|
|
|
|
#ifdef MAKEY |
|
|
fprintf(stderr, "魔キー空間バージョンにつき、シロウトにはおすすめできない。\n\n"); |
|
|
#endif /* MAKEY */ |
|
|
|
|
|
#ifdef ALLKEY |
|
|
fprintf(stderr, "真・全空間バージョンにつき、シロウトにはおすすめできない。\n\n"); |
|
|
#endif /* MAKEY */ |
|
|
|
|
|
if ( !cpuid_issupported() ) { |
|
|
fprintf( stderr, "この環境で走らせることが想定されていません。\n" ); |
|
|
exit( 1 ); |
|
|
} |
|
| 468 |
|
|
| 469 |
assert( (1 << N_STRIDE) == N_ALU * ALU_BITS ); |
mutex_key = CreateMutex(NULL, FALSE, NULL); |
| 470 |
|
|
| 471 |
/* タゲ読み込み */ |
/* タゲ読み込み */ |
| 472 |
root_expr = expr_parse( "target.txt" ); |
root_expr = expr_parse("target.txt"); |
|
|
|
|
if ( verbose ) { |
|
|
printf( "特殊検索オプション : " ); |
|
|
if ( special & ST_DOSU ) { |
|
|
printf( "怒数 " ); |
|
|
} else { |
|
|
if ( special & ST_ALLN ) { |
|
|
printf( "全数 " ); |
|
|
} |
|
|
} |
|
|
if ( special & ST_EROI ) { |
|
|
printf( "エロ " ); |
|
|
} |
|
|
if ( special & ST_NIKO ) { |
|
|
printf( "二構 " ); |
|
|
} |
|
|
if ( special & ST_BUOO ) { |
|
|
printf( "ぶお " ); |
|
|
} |
|
|
if ( special & ST_CHIN ) { |
|
|
printf( "ちん " ); |
|
|
} |
|
|
if ( special & ST_HREN ) { |
|
|
printf( "飛連 " ); |
|
|
} |
|
|
if ( special & ST_YAKU ) { |
|
|
printf( "八雲 " ); |
|
|
} |
|
|
if ( special ) { |
|
|
printf( "オン!\n" ); |
|
|
} else { |
|
|
printf( "オールオフ!\n" ); |
|
|
} |
|
|
if ( seedOffset != 0 ) { |
|
|
printf( "乱数の種のオフセット = %d\n", seedOffset ); |
|
|
} |
|
|
#ifdef REON |
|
|
if ( regExpStr[0] != '\0' ) { |
|
|
printf( "正規表現 : %s\n", regExpStr ); |
|
|
} |
|
|
#endif /* REON */ |
|
|
if ( gear != DEF_GEAR ) { |
|
|
printf( "がんばりぐあい : %d\n", gear ); |
|
|
} |
|
|
#ifdef KEYLOG |
|
|
if ( keyLog == MAKAI_TRUE ) { |
|
|
printf( "検索したキー空間のロギング\n" ); |
|
|
} |
|
|
#endif /* KEYLOG */ |
|
|
} |
|
| 473 |
|
|
| 474 |
/* コードを生成・展開 |
/* コードを生成・展開 |
| 475 |
起動予定スレッド数に応じて |
起動予定スレッド数に応じて |
| 476 |
生成するコードを変える */ |
生成するコードを変える */ |
| 477 |
sfp = scoreboard_open(); |
sfp = scoreboard_open(); |
| 478 |
/* prologue & コアループ */ |
fwrite(crypt64_descs[0]->pro, 1, crypt64_descs[0]->cmp_pro - crypt64_descs[0]->pro, sfp); /* prologue & コアループ */ |
| 479 |
fwrite( crypt64_descs[0]->pro, 1, |
proc_mask = thread_avail(); |
|
crypt64_descs[0]->cmp_pro - crypt64_descs[0]->pro, sfp ); |
|
|
|
|
|
/* proc_mask に使用する CPU のマスクをセット */ |
|
|
if ( pmask == 0 ) { |
|
|
/* 指定がなければ、使える CPU 全部 */ |
|
|
proc_mask = thread_avail(); |
|
|
} else { |
|
|
/* 指定された CPU の存在チェック。だが、今は Win32 のコードしかない。 */ |
|
|
#ifdef WIN32 |
|
|
DWORD_PTR processMask, systemMask; |
|
|
if ( GetProcessAffinityMask( GetCurrentProcess(), &processMask, &systemMask ) |
|
|
== 0 ) { |
|
|
printf( "CPU の割り当てに失敗 その 1\n" ); |
|
|
exit( 1 ); |
|
|
} |
|
|
if ( (processMask & pmask) != pmask ) { |
|
|
printf( "そんな CPU はねぇ!\n" ); |
|
|
exit( 1 ); |
|
|
} |
|
|
#endif /* WIN32 */ |
|
|
|
|
|
proc_mask = pmask; |
|
|
printf( "CPU : " ); |
|
|
for ( i = 0; i < MAX_THREAD; i++ ) { |
|
|
if ( pmask & 1 ) { |
|
|
printf( "%d ", i ); |
|
|
} |
|
|
pmask >>= 1; |
|
|
} |
|
|
printf( "を使用します。\n" ); |
|
| 480 |
|
|
| 481 |
/* CPU の割り当て。だが、今は Wi(r */ |
#if 0 |
| 482 |
#ifdef WIN32 |
if (0&&proc_mask == 1U) |
| 483 |
if ( SetProcessAffinityMask( GetCurrentProcess(), proc_mask ) == 0 ) { |
{ |
| 484 |
printf( "CPU の割り当てに失敗 その 2\n" ); |
/* single */ |
| 485 |
exit( 1 ); |
code_cmp = 0; |
| 486 |
} |
} |
| 487 |
#endif /* WIN32 */ |
else |
| 488 |
} |
#endif |
| 489 |
|
{ |
| 490 |
/* スレッド数の指定がない場合は、proc_mask からゲッツ */ |
/* multi */ |
| 491 |
if ( nThread == 0 ) { |
fwrite(crypt64_descs[0]->ep, 1, crypt64_descs[0]->ep_end - crypt64_descs[0]->ep, sfp); /* epilogue */ |
| 492 |
nThread = popcnt64( proc_mask ); |
|
| 493 |
} |
/* 比較器のみを生成(前半) */ |
| 494 |
|
code_cmp = ftell(sfp); |
| 495 |
fprintf( stderr, "%d 個の検索スレッドを生成\n", nThread ); |
fseek(sfp, (-code_cmp) & 63, SEEK_CUR); |
| 496 |
|
code_cmp = ftell(sfp); |
| 497 |
if ( nThread == 1 ) { |
fwrite(crypt64_descs[0]->pro, 1, crypt64_descs[0]->crypt - crypt64_descs[0]->pro, sfp); /* prologue */ |
| 498 |
npkts = 1; |
} |
|
pkts_vacant = 1; |
|
|
code_cmp = 0; |
|
|
} else { |
|
|
/* epilogue */ |
|
|
fwrite( crypt64_descs[0]->ep, 1, |
|
|
crypt64_descs[0]->ep_end - crypt64_descs[0]->ep, sfp ); |
|
|
/* 比較器のみを生成(前半) */ |
|
|
code_cmp = ftell( sfp ); |
|
|
fseek( sfp, (-code_cmp) & 63, SEEK_CUR ); |
|
|
code_cmp = ftell( sfp ); |
|
|
/* prologue */ |
|
|
fwrite( crypt64_descs[0]->pro, 1, |
|
|
crypt64_descs[0]->crypt - crypt64_descs[0]->pro, sfp ); |
|
|
npkts = 64; |
|
|
pkts_vacant = (uint64_t)-1; /* (1 << 64) - 1 を計算したくない */ |
|
|
} |
|
| 499 |
|
|
| 500 |
/* 比較部を生成 */ |
/* 比較部を生成 */ |
| 501 |
/* 比較器準備 */ |
fwrite(crypt64_descs[0]->cmp_pro, 1, crypt64_descs[0]->cmp_ep - crypt64_descs[0]->cmp_pro, sfp); /* 比較器準備 */ |
| 502 |
fwrite( crypt64_descs[0]->cmp_pro, 1, |
tn = synth_synthesize(sfp, root_expr); |
| 503 |
crypt64_descs[0]->cmp_ep - crypt64_descs[0]->cmp_pro, sfp ); |
fwrite(crypt64_descs[0]->cmp_ep, 1, crypt64_descs[0]->ep_end - crypt64_descs[0]->cmp_ep, sfp); /* epilogue */ |
| 504 |
tn = synth_synthesize( sfp, root_expr ); |
|
|
/* epilogue */ |
|
|
fwrite( crypt64_descs[0]->cmp_ep, 1, |
|
|
crypt64_descs[0]->ep_end - crypt64_descs[0]->cmp_ep, sfp ); |
|
| 505 |
/* コードをメモリに貼り付ける */ |
/* コードをメモリに貼り付ける */ |
| 506 |
code = scoreboard_map( sfp ); |
code = scoreboard_map(sfp); |
| 507 |
|
|
| 508 |
/* キーの初期化 */ |
/* キーの初期化 */ |
| 509 |
if ( seed == 0 ) { |
WaitForSingleObject(mutex_key, INFINITE); |
| 510 |
seed = (unsigned int)time( NULL ) + seedOffset; |
srand(usec()); |
| 511 |
} |
key_init(&key); |
| 512 |
if ( verbose ) { |
ReleaseMutex(mutex_key); |
| 513 |
printf( "乱数の種 = %u\n", seed ); |
set_salt(code, crypt64_descs[0], key.key); |
|
} |
|
|
srand( seed ); |
|
|
|
|
|
#ifdef KEYCHK |
|
|
{ |
|
|
int i; |
|
|
|
|
|
for ( i = 0; i < 100000; i++ ) { |
|
|
printf( "%02x %02x %02x %02x %02x %02x %02x %02x\n", |
|
|
key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7] ); |
|
|
key_init( key ); |
|
|
} |
|
|
exit( 0 ); |
|
|
} |
|
|
#endif /* KEYCHK */ |
|
| 514 |
|
|
| 515 |
key_init( key ); |
if (log_open("log.txt") != 0) return 1; |
|
set_salt( code, crypt64_descs[0], key ); |
|
| 516 |
|
|
| 517 |
/* 演算パケットを作成 */ |
WaitForSingleObject(mutex_key, INFINITE); |
|
pkts = packet_create( npkts, tn, key ); |
|
|
pkt_hit = &pkts[npkts - 1]; |
|
| 518 |
|
|
| 519 |
/* 働くおじさんを量産 */ |
/* 働くおじさんを量産 */ |
|
thread_create_event( event_ks_activated, 1 ); |
|
|
ks_activated = 1; |
|
| 520 |
nthreads = 0; |
nthreads = 0; |
| 521 |
if ( code_cmp ) { |
if (code_cmp) |
| 522 |
THREAD_TH_T h; |
{ |
| 523 |
int ots = -1; |
THREAD_TH_T h; |
| 524 |
threads = calloc( 2 * nThread, sizeof(*threads) ); |
int ots = -1; |
| 525 |
for ( i = 0; i < nThread; i++ ) { |
threads = calloc(2 * popcnt64(proc_mask), sizeof(*threads)); |
| 526 |
if ( ots < 0 ) { |
for (i = 0; i < 64; i++) |
| 527 |
/* 自分自身のスケジューリング |
if (proc_mask & (1ULL << i)) |
| 528 |
こーゆー系のアプリは低めに設定するのが吉(かも) */ |
{ |
| 529 |
|
if (0&&ots < 0) |
| 530 |
|
{ |
| 531 |
|
/* 自分自身のスケジューリング |
| 532 |
|
こーゆー系のアプリは低めに設定するのが吉(かも) */ |
| 533 |
#ifdef WIN32 |
#ifdef WIN32 |
| 534 |
h = GetCurrentProcess(); |
h = GetCurrentProcess(); |
| 535 |
/* todo 基本優先度の設定が二箇所にある */ |
SetPriorityClass(h, BELOW_NORMAL_PRIORITY_CLASS); |
| 536 |
SetPriorityClass( h, BELOW_NORMAL_PRIORITY_CLASS ); |
#endif |
| 537 |
#endif |
#if defined(thread_set_priority) |
| 538 |
#if defined( thread_set_priority ) |
/* 心の隙間お埋めします */ |
| 539 |
/* 心の隙間お埋めします */ |
threads[nthreads].code = code; |
| 540 |
threads[nthreads].code = code; |
threads[nthreads].code_cmp = code_cmp; |
| 541 |
threads[nthreads].p_ev_ks_activated = &event_ks_activated; |
threads[nthreads].seed = rand(); |
| 542 |
threads[nthreads].p_nidle = &nidle; |
threads[nthreads].pri = THREAD_PRIORITY_IDLE; |
| 543 |
threads[nthreads].pri = THREAD_PRIORITY_IDLE; |
thread_create(h, thread_crypt64_new, &threads[nthreads]); |
| 544 |
thread_create( h, thread_crypt64, &threads[nthreads] ); |
nthreads++; |
| 545 |
threads[nthreads].th = h; |
#endif |
| 546 |
nthreads++; |
if (!code_cmp) |
| 547 |
#endif |
break; |
| 548 |
if ( !code_cmp ) break; |
|
| 549 |
/* 自分自身の残りの設定を、あとでやる */ |
/* 自分自身の残りの設定を、あとでやる */ |
| 550 |
ots = i; |
ots = i; |
| 551 |
} else { |
} |
| 552 |
/* 他スレッドは、やや低めの優先度で。 */ |
else |
| 553 |
threads[nthreads].code = code; |
{ |
| 554 |
threads[nthreads].p_ev_ks_activated = &event_ks_activated; |
/* 他スレッドは、やや低めの優先度で。 */ |
| 555 |
threads[nthreads].p_nidle = &nidle; |
threads[nthreads].code = code; |
| 556 |
|
threads[nthreads].code_cmp = code_cmp; |
| 557 |
|
threads[nthreads].seed = rand(); |
| 558 |
#ifdef thread_set_priority |
#ifdef thread_set_priority |
| 559 |
threads[nthreads].pri = THREAD_PRIORITY_BELOW_NORMAL; |
//threads[nthreads].pri = THREAD_PRIORITY_BELOW_NORMAL; |
| 560 |
|
threads[nthreads].pri = THREAD_PRIORITY_LOWEST; |
| 561 |
#endif |
#endif |
| 562 |
thread_create( h, thread_crypt64, &threads[nthreads] ); |
thread_create(h, thread_crypt64_new, &threads[nthreads]); |
| 563 |
|
#ifdef thread_get_tid |
| 564 |
|
thread_set_affinity(h, i); |
| 565 |
|
#endif |
| 566 |
|
nthreads++; |
| 567 |
|
#if 1 |
| 568 |
|
/* IDLE */ |
| 569 |
|
threads[nthreads].code = code; |
| 570 |
|
threads[nthreads].code_cmp = code_cmp; |
| 571 |
|
threads[nthreads].seed = rand(); |
| 572 |
#ifdef thread_set_priority |
#ifdef thread_set_priority |
| 573 |
threads[nthreads].th = h; |
threads[nthreads].pri = THREAD_PRIORITY_IDLE; |
| 574 |
|
#endif |
| 575 |
|
thread_create(h, thread_crypt64_new, &threads[nthreads]); |
| 576 |
|
#ifdef thread_get_tid |
| 577 |
|
SetThreadAffinityMask(h, proc_mask); |
| 578 |
|
#endif |
| 579 |
|
nthreads++; |
| 580 |
|
#endif |
| 581 |
|
} |
| 582 |
|
} |
| 583 |
|
#ifdef thread_get_tid |
| 584 |
|
if (ots) |
| 585 |
|
thread_set_affinity(thread_get_tid(), ots); |
| 586 |
#endif |
#endif |
| 587 |
nthreads++; |
} |
| 588 |
} |
|
| 589 |
} |
fprintf(stderr, "検索開始!\n"); |
| 590 |
} |
ReleaseMutex(mutex_key); |
|
|
|
|
if ( (ofp = fopen( "log.txt", "at" )) == NULL ) { |
|
|
perror( "log.txt" ); |
|
|
return errno; |
|
|
} |
|
|
setvbuf(ofp, NULL, _IONBF, BUFSIZ); |
|
|
|
|
|
if ( (tfp = fopen( "logspe.txt", "at" )) == NULL ) { |
|
|
perror( "logspe.txt" ); |
|
|
return errno; |
|
|
} |
|
|
setvbuf( tfp, NULL, _IONBF, BUFSIZ ); |
|
|
if ( (nfp = fopen( "lognum.txt", "at" )) == NULL ) { |
|
|
perror( "lognum.txt" ); |
|
|
return errno; |
|
|
} |
|
|
setvbuf( nfp, NULL, _IONBF, BUFSIZ ); |
|
|
if ( (cfp = fopen( "logchi.txt", "at" )) == NULL ) { |
|
|
perror( "logchi.txt" ); |
|
|
return errno; |
|
|
} |
|
|
setvbuf( cfp, NULL, _IONBF, BUFSIZ ); |
|
|
#ifdef REON |
|
|
if ( (rfp = fopen( "logreg.txt", "at" )) == NULL ) { |
|
|
perror( "logreg.txt" ); |
|
|
return errno; |
|
|
} |
|
|
setvbuf( rfp, NULL, _IONBF, BUFSIZ ); |
|
|
#endif /* REON */ |
|
| 591 |
|
|
| 592 |
mincnt = 0x7FFFFFFF; |
mincnt = 0x7FFFFFFF; |
| 593 |
nblk_hit = nblk_total = 0; |
|
|
nap_hit = nap_total = 0; |
|
| 594 |
cr = 0; |
cr = 0; |
| 595 |
memset( &status, 0, sizeof( struct status ) ); |
memset( &status, 0, sizeof( struct status ) ); |
| 596 |
status.startTime = status.lastTime = usec(); |
status.startTime = status.lastTime = usec(); |
| 597 |
|
|
|
#ifdef MINAST |
|
|
#undef assert |
|
|
#define assert(x) |
|
|
#endif /* MINAST */ |
|
|
|
|
|
#ifdef SCTEST |
|
|
{ |
|
|
int i; |
|
|
|
|
|
for ( i = 1; i < SCTEST; i++ ) { |
|
|
key_reset( key, 0 ); |
|
|
} |
|
|
exit( 0 ); |
|
|
} |
|
|
#endif /* SCTEST */ |
|
|
|
|
| 598 |
/* 探索ループだぞっと */ |
/* 探索ループだぞっと */ |
| 599 |
for ( ;; ) { |
for (;;) |
| 600 |
struct PACKET_CRYPT64 *pkt_c; |
{ |
| 601 |
uint64_t cnt; |
Sleep(5000); |
|
#if DEBUG>=1 |
|
|
int cnt1, cnt2; |
|
|
#endif |
|
|
int k, kk; |
|
| 602 |
|
|
| 603 |
/* 比較器候補(may be NULL) |
/* 速度計測 */ |
| 604 |
先にキューから取り出す */ |
status.loop = 0; |
| 605 |
pkt_c = q_cmp[WRAP( rp_cmp, NQ_CMP )]; |
for (i = 0; i < n_cpus; i++) status.loop += loop_cpu[i]; |
|
if ( pkt_c != NULL && WRAP( rp_cmp, NQ_CMP ) != WRAP( wp_cmp, NQ_CMP ) ) { |
|
|
pkt_c = LOCK_CASP( &q_cmp[WRAP( rp_cmp, NQ_CMP )], NULL, pkt_c ); |
|
|
assert( pkt_c != NULL ); |
|
|
LOCK_INC( &rp_cmp ); |
|
|
/* パケットを vacant に回しておく */ |
|
|
pkts_vacant |= 1ULL << (pkt_c - pkts); |
|
|
} |
|
|
|
|
|
/* Saltチェンジ待ち */ |
|
|
if ( !ks_activated ) { |
|
|
ATOMWORD_T rp; |
|
|
if ( pkt_c == NULL ) { |
|
|
if ( (rp = rp_crypt, WRAP( rp, NQ_CRYPT ) != WRAP( wp_crypt, NQ_CRYPT )) |
|
|
&& LOCK_CAS( &rp_crypt, rp + 1, rp ) == rp ) { |
|
|
/* !ks_activate 状態では、自らも要求キューをやっつけにいく */ |
|
|
rp = WRAP( rp, NQ_CRYPT ); |
|
|
pkt_c = q_crypt[rp]; |
|
|
assert( pkt_c != NULL ); |
|
|
pkt_c = LOCK_CASP( &q_crypt[rp], NULL, pkt_c ); |
|
|
assert( pkt_c != NULL ); |
|
|
assert( pkt_c != pkt_hit ); |
|
|
CALL_CRYPT64( code, &pkt_c->key64, &pkt_c->param64 ); |
|
|
/* パケットを vacant に回しておく */ |
|
|
pkts_vacant |= 1ULL << (pkt_c - pkts); |
|
|
} else { |
|
|
/* やはりすることがないのでまったりと過ごす */ |
|
|
if ( nidle != nthreads ) thread_sleep(1); |
|
|
} |
|
|
} |
|
|
if ( nidle == nthreads ) { |
|
|
assert( WRAP( rp_crypt, NQ_CRYPT ) == WRAP( wp_crypt, NQ_CRYPT ) ); |
|
|
/* Salt チェンジが可能 */ |
|
|
set_salt( code, crypt64_descs[0], key ); |
|
|
if ( nthreads ) thread_signal_event( event_ks_activated ); |
|
|
ks_activated = 1; |
|
|
} |
|
|
} |
|
|
|
|
|
/* 鍵をキューにたたき込みまくる */ |
|
|
if ( !ks_activated ) { |
|
|
/* 鍵を登録しない */ |
|
|
; |
|
|
} else { |
|
|
for ( i = npkts - 1; i >= 0; i-- ) { |
|
|
if ( pkts_vacant & (1ULL << i) ) { |
|
|
int j; |
|
|
if ( i == npkts - 1 ) { |
|
|
/* 前段で、働くおじさんから結果をもらっていたら、何もしない */ |
|
|
if ( pkt_c != NULL ) continue; |
|
|
} else { |
|
|
/* 前段で取り出したばかりの働くおじさんは、尊重する */ |
|
|
if ( &pkts[i] == pkt_c ) continue; |
|
|
/* queue full の場合は見送る */ |
|
|
/* XXX 16 はてきとう */ |
|
|
if ( WRAP( wp_crypt, NQ_CRYPT ) == WRAP( rp_crypt - 16, NQ_CRYPT ) |
|
|
|| q_crypt[WRAP( wp_crypt, NQ_CRYPT )] != NULL ) break; |
|
|
} |
|
|
/* 鍵のセット */ |
|
|
for ( j = 0; j < 8; j++ ) { |
|
|
key_set64( &pkts[i].key64, j, key[j], key[j] ^ pkts[i].uk.key[j], 0 ); |
|
|
pkts[i].uk.key[j] = key[j]; |
|
|
} |
|
|
if ( i == npkts - 1 ) { |
|
|
/* 次段で CRYPT64->CMP */ |
|
|
assert(pkt_c == NULL); |
|
|
pkt_c = &pkts[i]; |
|
|
assert( pkt_c == pkt_hit ); |
|
|
} else { |
|
|
/* キューにたたき込む */ |
|
|
while ( LOCK_CASP( &q_crypt[WRAP( wp_crypt, NQ_CRYPT )], &pkts[i], NULL ) |
|
|
!= NULL ) { |
|
|
/* 設計上はここに来ない */ |
|
|
fprintf( stderr, |
|
|
"q_crypt を汚してるのは誰だ? (rp=%3d, wp=%3d, v=%08X%08X)\n", |
|
|
(unsigned)WRAP( rp_crypt, NQ_CRYPT ), |
|
|
(unsigned)WRAP( wp_crypt, NQ_CRYPT ), |
|
|
(unsigned)( pkts_vacant >> 32 ), |
|
|
(unsigned)pkts_vacant ); |
|
|
thread_sleep( 1000 ); |
|
|
} |
|
|
LOCK_INC( &wp_crypt ); |
|
|
pkts_vacant ^= 1ULL << i; |
|
|
assert( !(pkts_vacant & (1ULL << i)) ); /* 削れ */ |
|
|
} |
|
|
/* 鍵増加はこんなところに移動! */ |
|
|
assert( ks_activated ); |
|
|
if ( !key_inc( key, 6 ) && !key_inc( key, umeLen ) ) { |
|
|
/* 鍵のシャッフル q_crypt が捌けるまで、set_salt() はできない */ |
|
|
#if DEBUG>=1 |
|
|
fprintf( stderr, "********************************SHUFFLE!\n" ); |
|
|
#endif |
|
|
if ( nthreads ) thread_clear_event( event_ks_activated ); |
|
|
key_reset( key, 0 ); |
|
|
/* キューの鍵が捌けるまでアイドル状態に */ |
|
|
ks_activated = 0; |
|
|
/* スレッドをブーストして回る */ |
|
|
#ifdef thread_set_priority |
|
|
for ( j = 0; j < nthreads; j++ ) { |
|
|
assert( threads != NULL ); |
|
|
thread_set_priority( threads[j].th, THREAD_PRIORITY_NORMAL ); |
|
|
} |
|
|
#endif |
|
|
/* ループ続行はもはや不要 */ |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
/* することがなくなっている場合 */ |
|
|
if ( pkt_c == NULL ) { |
|
|
assert( !ks_activated ); |
|
|
continue; |
|
|
} |
|
|
/* 呼ぶ! |
|
|
LR 初期化は、サブモジュール内で行うべし |
|
|
FASTCALL に準じた呼び出しのため、 |
|
|
ホントはいろいろレジスタが破壊されるハズ…なんだが。 */ |
|
|
if ( pkt_c != pkt_hit ) { |
|
|
assert( code_cmp != 0 ); |
|
|
cnt = CALL_CMP64( code + code_cmp, pkt_hit->param64.hit, |
|
|
pkt_c->param64.lr ); |
|
|
} else { |
|
|
/* ようやく自スレッドで回せる */ |
|
|
cnt = CALL_CRYPT64( code, &pkt_c->key64, &pkt_c->param64 ); |
|
|
if ( code_cmp ) { |
|
|
cnt = CALL_CMP64( code + code_cmp, pkt_c->param64.hit, |
|
|
pkt_c->param64.lr ); |
|
|
} |
|
|
} |
|
|
/* ヒットしたときの処理 |
|
|
key および lr は pkt_c に合致判定は pkt_hit に入っているハズ */ |
|
|
xhash_loaded = 0; |
|
|
for ( kk = 0; kk < N_ALU; kk++ ) { |
|
|
ALU_T t; |
|
|
static uint64_t xhash[64]; |
|
|
if ( special |
|
|
#ifdef REON |
|
|
|| regExpStr[0] != '\0' |
|
|
#endif /* REON */ |
|
|
) { |
|
|
CALL_TR64( &pkt_c->param64.lr[0][0].q[kk / (N_ALU / N_Q)], xhash ); |
|
|
xhash_loaded = 1; |
|
|
} |
|
|
if ( !(kk & (N_ALU / N_Q - 1)) ) nblk_total++, xhash_loaded = 0; |
|
|
if ( special |
|
|
#ifdef REON |
|
|
|| regExpStr[0] != '\0' |
|
|
#endif /* REON */ |
|
|
) { |
|
|
char hash[16]; |
|
|
FILE *lfp; |
|
|
unsigned char kind[3]; |
|
|
for ( k = 0; k < ALU_BITS; k++ ) { |
|
|
for ( i = 1; i < 11; i++ ) { |
|
|
unsigned c = 0; |
|
|
c = (xhash[(ALU_BITS * kk + k) & 63] >> (6 * (i - 1))) & 0x3F; |
|
|
hash[i - 1] = C64[c]; |
|
|
} |
|
|
hash[10] = 0; |
|
|
#ifdef REON |
|
|
if ( regExpStr[0] != '\0' ) { |
|
|
if ( regexec( ®Exp, hash, (size_t)0, NULL, 0 ) == 0 ) { |
|
|
if ( cr ) fprintf( stderr, "\n" ); |
|
|
cr = 0; |
|
|
#ifdef NAMA |
|
|
hit( rfp, hash, pkt_c->uk.key, kk, k, "正", MAKAI_FALSE ); |
|
|
#else /* NAMA */ |
|
|
hit( rfp, hash, pkt_c->uk.key, kk, k, "正", MAKAI_TRUE ); |
|
|
#endif /* NAMA */ |
|
|
} |
|
|
} |
|
|
#endif /* REON */ |
|
|
if ( special ) { |
|
|
if ( (lfp = checkSpecial( hash, kind )) != NULL ) { |
|
|
if ( cr ) fprintf( stderr, "\n" ); |
|
|
cr = 0; |
|
|
#ifdef NAMA |
|
|
hit( lfp, hash, pkt_c->uk.key, kk, k, kind, MAKAI_FALSE ); |
|
|
#else /* NAMA */ |
|
|
hit( lfp, hash, pkt_c->uk.key, kk, k, kind, MAKAI_TRUE ); |
|
|
#endif /* NAMA */ |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
t = pkt_hit->param64.hit[HIT_ANY].a[kk]; |
|
|
if ( !t ) continue; |
|
|
nap_total += ALU_BITS; |
|
|
for ( k = 0; k < ALU_BITS; k++ ) { |
|
|
char hash[16]; |
|
|
int hitLen; |
|
|
if ( !(t & ((ALU_T)1 << k)) ) continue; |
|
|
nap_hit++; |
|
|
/* 転置 */ |
|
|
if ( !xhash_loaded ) { |
|
|
nblk_hit++; |
|
|
CALL_TR64( &pkt_c->param64.lr[0][0].q[kk / (N_ALU / N_Q)], xhash ); |
|
|
xhash_loaded = 1; |
|
|
} |
|
|
/* 辞書を調べる */ |
|
|
hitLen = 0; |
|
|
if ( !((pkt_hit->param64.hit[HIT_BOOL].a[kk] & ((ALU_T)1 << k)) |
|
|
|| (hitLen = wdict_ishit( pkt_hit->param64.hit, kk, k, |
|
|
xhash[(ALU_BITS * kk + k) & 0x3F]))) ) |
|
|
continue; |
|
|
for ( i = 1; i < 11; i++ ) { |
|
|
unsigned c; |
|
|
c = (xhash[(ALU_BITS * kk + k) & 63] >> (6 * (i - 1))) & 0x3F; |
|
|
hash[i - 1] = C64[c]; |
|
|
} |
|
|
hash[10] = 0; |
|
|
if ( cr ) fprintf( stderr, "\n" ); |
|
|
cr = 0; |
|
|
{ |
|
|
unsigned char len[10]; |
|
|
#ifdef SELF |
|
|
static hitCount = 0; |
|
|
#endif /* SELF */ |
|
|
|
|
|
sprintf( len, "%02d", hitLen ); |
|
|
if ( hitLen < 10 ) { |
|
|
/* たまたま後ろに区切り文字が付いた場合、一桁目を E にする */ |
|
|
if ( hash[hitLen] == '.' || hash[hitLen] == '/' ) { |
|
|
len[0] = 'E'; |
|
|
} |
|
|
} |
|
|
|
|
|
#if SEQ > 0 /* だがしかし、SEQ == 8 の場合しか考えてない */ |
|
|
/* 連モノの処理方法をちゃんと追いかけるべきだが、めんどくさいのでこれで */ |
|
|
if ( hitLen == 0 ) [ |
|
|
char ref; |
|
|
ref = hash[2]; |
|
|
if ( ref == hash[3] && ref == hash[4] && ref == hash[5] && |
|
|
ref == hash[6] && ref == hash[7] ) { |
|
|
if ( ref == hash[0] && ref == hash[1] ) { |
|
|
strcpy( len, "勝" ); |
|
|
} |
|
|
if ( ref == hash[1] && ref == hash[8] ) { |
|
|
strcpy( len, "勝" ); |
|
|
} |
|
|
if ( ref == hash[8] && ref == hash[9] ) { |
|
|
strcpy( len, "勝" ); |
|
|
} |
|
|
} |
|
|
} |
|
|
#endif /* SEQ */ |
|
|
|
|
|
#ifdef NAMA |
|
|
hit( ofp, hash, pkt_c->uk.key, kk, k, len, MAKAI_FALSE ); |
|
|
#else /* NAMA */ |
|
|
hit( ofp, hash, pkt_c->uk.key, kk, k, len, MAKAI_TRUE ); |
|
|
#endif /* NAMA */ |
|
|
|
|
|
#ifdef SELF |
|
|
hitCount++; |
|
|
if ( hitCount >= SELF_LIM_CNT ) { |
|
|
exit( 0 ); |
|
|
} |
|
|
#endif /* SELF */ |
|
|
} |
|
|
} |
|
|
} |
|
| 606 |
|
|
| 607 |
/* 速度計測 */ |
if (status.loop >= status.lastloop + upd_int |
| 608 |
status.loop += N_ALU * ALU_BITS; |
&& (curTime = usec()) != status.lastTime) |
| 609 |
|
{ |
| 610 |
|
uint64_t diffTime; |
| 611 |
|
int a, b, c; |
| 612 |
|
/* 通算(単位 ktrips/sec) */ |
| 613 |
|
diffTime = curTime - status.startTime; |
| 614 |
|
a = status.loop / ((1000 / USEC_SEC) * diffTime); |
| 615 |
|
|
| 616 |
|
/* 区間(単位 trips/sec) */ |
| 617 |
|
diffTime = curTime - status.lastTime; |
| 618 |
|
b = USEC_SEC * (status.loop - status.lastloop) / diffTime; |
| 619 |
|
|
| 620 |
|
/* 予測 */ |
| 621 |
|
c = UPDATE_INTERVAL * b; |
| 622 |
|
|
| 623 |
|
/* 立ち上がりなど、誤差があり upd_int が小さすぎたときは |
| 624 |
|
いきなり全補正せず 1 秒(==b)づつ収斂させる。 */ |
| 625 |
|
upd_int = (upd_int + b < c |
| 626 |
|
? upd_int + b |
| 627 |
|
: c); |
| 628 |
|
|
| 629 |
/* -g オプション用のコードは、Win32 用しかない */ |
status.lastTime = curTime; |
| 630 |
/* todo UNIX 系用コードも要るかな */ |
status.lastloop = status.loop; |
| 631 |
#if defined(WIN32) |
#if DEBUG>=1 |
| 632 |
if ( sCnt >= YOUSUMI ) { |
fprintf(stderr, |
| 633 |
lCnt++; |
"%5d/%5d(%3d%%)", |
| 634 |
if ( lCnt > lCntMax ) { |
nblk_hit, nblk_total, 100 * nblk_hit / nblk_total); |
| 635 |
Sleep( (DWORD)10 ); |
nblk_hit = nblk_total = 0; |
| 636 |
lCnt = 0; |
if (nap_total) |
| 637 |
} |
fprintf(stderr, |
| 638 |
} |
" %5d/%5d(%3d%%)", |
| 639 |
#endif /* WIN32 */ |
nap_hit, nap_total, 100 * nap_hit / nap_total); |
| 640 |
|
else |
| 641 |
if ( status.loop >= status.lastloop + upd_int |
fprintf(stderr, |
| 642 |
&& (curTime = usec()) != status.lastTime ) { |
" -----/-----(---%%)"); |
| 643 |
uint64_t diffTime; |
nap_hit = nap_total = 0; |
| 644 |
int a, b, c; |
#endif |
| 645 |
/* 通算(単位 ktrips/sec) */ |
fprintf(stderr, |
| 646 |
diffTime = curTime - status.startTime; |
"%4d.%03dMtrips/s [%4d.%06dMtrips/s]\r", |
| 647 |
#ifdef SELF |
a / 1000, a % 1000, |
| 648 |
if ( diffTime >= SELF_LIM_SEC ) { |
b / 1000000, b % 1000000); |
| 649 |
exit( 0 ); |
cr++; |
| 650 |
} |
} |
| 651 |
#endif /* SELF */ |
} |
|
a = status.loop / ((1000 / USEC_SEC) * diffTime); |
|
|
#ifdef BENCH |
|
|
if ( (diffTime / USEC_SEC) > (BENCH * 60) ) { |
|
|
fprintf( stderr, "\n%6dktrips/s\n", a ); |
|
|
exit( 0 ); |
|
|
} |
|
|
#endif /* BENCH */ |
|
|
/* 区間(単位 trips/sec) */ |
|
|
diffTime = curTime - status.lastTime; |
|
|
b = USEC_SEC * (status.loop - status.lastloop) / diffTime; |
|
|
#if defined(WIN32) |
|
|
if ( gear != DEF_GEAR ) { |
|
|
if ( sCnt < YOUSUMI ) { |
|
|
if ( b > maxSpeed ) { |
|
|
maxSpeed = b; |
|
|
/* x = l/s * (gear / (10 - gear)) / 100 */ |
|
|
lCntMax = maxSpeed / (N_ALU * ALU_BITS) * (gear * 1000 / (10 - gear)) / 100000; |
|
|
if ( lCntMax < 1 ) { |
|
|
lCntMax = 1; |
|
|
} |
|
|
} |
|
|
sCnt++; |
|
|
} |
|
|
} |
|
|
#endif /* WIN32 */ |
|
|
/* 予測 */ |
|
|
c = UPDATE_INTERVAL * b; |
|
|
/* 立ち上がりなど、誤差があり upd_int が小さすぎたときは |
|
|
いきなり全補正せず 1 秒(==b)づつ収斂させる。 */ |
|
|
upd_int = ( upd_int + b < c ? upd_int + b : c ); |
|
|
status.lastTime = curTime; |
|
|
status.lastloop = status.loop; |
|
|
fprintf( stderr, "%6dktrips/s [%6d.%03dktrips/s]\r", |
|
|
a, b / 1000, b % 1000 ); |
|
|
cr++; |
|
|
} |
|
|
} |
|
| 652 |
|
|
| 653 |
return 0; |
return 0; |
| 654 |
} |
} |