Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/mty-makai/mty.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 74 - (show annotations) (download) (as text)
Sun Apr 1 08:38:32 2007 UTC (17 years ago) by chapuni
Original Path: mty/mty.c
File MIME type: text/x-csrc
File size: 19940 byte(s)
大量検索もどきを実装。
すでにわかっている不具合がたくさんあるので、超地雷です。
あちこちに残っている制限はあとで外します。
数十万行を喰わせると死ぬほど遅いのはどうにかします。
1 /***********************************************************************
2 *
3 * file: mty.c
4 *
5 * まあ、待て屋。
6 *
7 * $Id$
8 *
9 */
10
11 #include <assert.h>
12 #include <ctype.h>
13 #include <errno.h>
14 #include <malloc.h>
15 #include <limits.h>
16 #include <stdarg.h>
17 #include <stddef.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <time.h>
22
23 #if defined(WIN32)
24
25 #include <windows.h>
26 #include <sys/timeb.h>
27
28 #elif defined(__GNUC__)
29
30 #include <sys/time.h>
31
32 #endif
33
34 #include "config.h"
35 #include "cp932.h"
36 #include "crypt64.h"
37 #include "desconst.h"
38 #include "expr_parse.h"
39 #include "scoreboard.h"
40 #include "synth.h"
41 #include "tr64.h"
42 #include "translate.h"
43
44 #if USE_DT
45 #include "dt4.h"
46 #endif
47
48 /* 鍵文字列 */
49 unsigned char key[8 + 8];
50 unsigned char okey[8 + 8];
51
52 /* 鍵クラス */
53 static
54 struct
55 {
56 unsigned cls;
57 unsigned map[256];
58 } kcls[8 + 8];
59
60
61 /* 拡張鍵クラス */
62 #define KCLS_DT0 64
63 #define KCLS_DT1 128
64 #define KCLS_K2 256
65
66 #if USE_DT
67 /* 鍵キメ用辞書インデクス */
68 struct DT *kd[8 + 8];
69
70 /* 辞書インデクス */
71 struct DT *dtidx[0x100 + 1];
72 #endif
73
74 /* 指定されたクラスと入っているキーから、classify を行う */
75 void
76 key_make_map(int n)
77 {
78 int i, j;
79 unsigned c = kcls[n].map[key[n]];
80
81 #if USE_DT
82 if (3 <= n && n < 7 && kd[n - 3])
83 {
84 /* 辞書のケツの文字。後ろにナニヤラキャラクタが来る */
85 c = kd[n - 3]->c[0];
86 if ((0x81 <= c && c <= 0x9F)
87 || (0xE0 <= c && c <= 0xFC))
88 c = KCLS_K2;
89 else
90 c = (cp932[256 * key[n]]
91 | cp932[256 * (key[n] ^ 0x80)]);
92 #if DEBUG>=1
93 printf("*n=%d, key=%02X, cls=%04X\n",
94 n,
95 key[n],
96 c);
97 #endif
98 }
99 else if (2 <= n && n < 6 && kd[n - 2])
100 {
101 return;
102 }
103 else if (1 <= n && n < 5 && kd[n - 1])
104 {
105 return;
106 }
107 else if (1 <= n && n < 5 && !kd[n - 1]
108 //&& (c & KCLS_K2)
109 && (c & KCLS_DT1))
110 {
111 /* 漢字2文字を拾っていきまつ */
112 #if DEBUG>=1
113 printf("(%d)%02X %02X(%02X:%02X:%02X:%02X)\n",
114 n, key[n - 1], key[n],
115 cp932[(256 * key[n - 1] + key[n])],
116 cp932[(256 * key[n - 1] + key[n]) ^ 0x0080],
117 cp932[(256 * key[n - 1] + key[n]) ^ 0x8000],
118 cp932[(256 * key[n - 1] + key[n]) ^ 0x8080]);
119 #endif
120 if (n != 1 && n != 2
121 && (cp932[(256 * key[n - 1] + key[n]) ^ 0x0080] & KCLS_DT1))
122 key[n] ^= 0x80;
123 else if (n != 2 && n != 3
124 && (cp932[(256 * key[n - 1] + key[n]) ^ 0x8000] & KCLS_DT1))
125 key[n - 1] ^= 0x80;
126 else if (n > 3 && (cp932[(256 * key[n - 1] + key[n]) ^ 0x8080] & KCLS_DT1))
127 key[n - 1] ^= 0x80, key[n] ^= 0x80;
128 if (cp932[256 * key[n - 1] + key[n]] & KCLS_DT1)
129 {
130 for (kd[n - 1] = dtidx[key[n - 1]];
131 kd[n - 1]->c[1] != key[n];
132 kd[n - 1]++)
133 assert(kd[n - 1]->c[0] == key[n - 1]);
134 #if DEBUG>=1
135 printf("(%02X%02X:%02X%02X)%c%c%c%c\n",
136 kd[n - 1]->c[0],
137 kd[n - 1]->c[1],
138 kd[n - 1]->c[2],
139 kd[n - 1]->c[3],
140 kd[n - 1]->c[0],
141 kd[n - 1]->c[1],
142 kd[n - 1]->c[2],
143 kd[n - 1]->c[3]);
144 #endif
145 return;
146 }
147 }
148 else if (n < 4 && (c & KCLS_DT0) && kd[n] == NULL)
149 {
150 /* カタカナ埋め込みいきます */
151 assert(kd[n] == NULL);
152 #if DEBUG>=1
153 printf("n=%d, key=%02X\n", n, key[n]);
154 #endif
155 kd[n] = dtidx[key[n]];
156 if (!kd[n]
157 && !(n == 1 || n == 2)
158 && dtidx[key[n] ^ 0x80])
159 {
160 key[n] ^= 0x80;
161 kd[n] = dtidx[key[n]];
162 }
163 if (kd[n])
164 return;
165 }
166 else
167 {
168 kd[n] = NULL;
169 }
170 #endif
171
172 /* 最後の部分は class map を生成する必要ナシ */
173 if (n >= 6)
174 return;
175
176 for (i = 0; i < 256; i++)
177 {
178 unsigned bm = 0;
179 #if 1
180 if (c & KCLS_K1)
181 {
182 if (cp932[256 * key[n] + i] & KCLS_K1)
183 bm |= KCLS_K2 | (cp932[256 * key[n] + i] & KCLS_DT1);
184 if (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_K1)
185 bm |= KCLS_K2 | (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_DT1);
186 #if 0
187 bm |= ((cp932[256 * key[n] + i] & KCLS_K1)
188 || (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_K1)
189 ? KCLS_K2 : 0);
190 #endif
191 }
192 if (c & (KCLS_AN | KCLS_KA | KCLS_K2))
193 for (j = 0; j < 256; j++)
194 {
195 bm |= cp932[256 * i + j] & (KCLS_AN | KCLS_KA | KCLS_K1
196 | KCLS_DT0);
197 #if 0
198 if (j >= 127 && !(n == 0 || n == 1))
199 break;
200 #endif
201 }
202 kcls[n + 1].map[i] = bm;
203 #endif
204 if (i >= 128 && !(n == 0 || n == 1))
205 kcls[n + 1].map[i - 128] |= kcls[n + 1].map[i];
206 }
207
208 if (n < 6)
209 kcls[n + 1].map[0x00] = kcls[n + 1].map[0x80] = 0;
210 if (n == 6)
211 kcls[7].map[0x00] |= KCLS_AN;
212 }
213
214 #if USE_DT
215 unsigned
216 dt_get(int kdn,
217 int xn,
218 int n,
219 int ch)
220 {
221 int i;
222 #if DEBUG>=1
223 printf("*dt_get(%d)%c%c%c%c(%02X%02X:%02X%02X)->ch=%d",
224 n,
225 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
226 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
227 ch);
228 #endif
229 /* まずは数える */
230 for (i = 0;
231 kd[kdn][i].c[xn] == kd[kdn]->c[xn];
232 i++)
233 ;
234 assert(i > 0);
235 kd[kdn] += ch % i;
236 #if DEBUG>=1
237 printf("/%d\n dt_get: %c%c%c%c(%02X%02X:%02X%02X)->ch=%d\n",
238 i,
239 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
240 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
241 ch);
242 #endif
243 return kd[kdn]->c[n];
244 }
245 #endif
246
247 /* マップから文字を拾ってセット */
248 unsigned
249 key_set(int n, unsigned ch)
250 {
251 int cnt = 0, i;
252
253 #if USE_DT
254 if (3 <= n && n < 7 && kd[n - 3])
255 {
256 return dt_get(n - 3, 2, 3, ch);
257 return kd[n - 3]->c[3];
258 }
259 else if (2 <= n && n < 6 && kd[n - 2])
260 {
261 return dt_get(n - 2, 1, 2, ch);
262 return kd[n - 2]->c[2];
263 }
264 else if (1 <= n && n < 5 && kd[n - 1])
265 {
266 return dt_get(n - 1, 0, 1, ch);
267 return kd[n - 1]->c[1];
268 }
269 #endif
270
271 #if DEBUG>=3
272 if (cnt == 0)
273 {
274 printf("n=%d, ch=%d, (n-1)=%02X\n", n, ch, key[n - 1]);
275 int j;
276 for (i = 0; i < 16; i++)
277 {
278 printf("map[0x%02X] =", 16 * i);
279 for (j = 0; j < 16; j++)
280 printf(" %03X", kcls[n].map[16 * i + j]);
281 printf("\n");
282 }
283 }
284 #endif
285 for (i = 0; i < 256; i++)
286 {
287 if (kcls[n].map[i])
288 {
289 if (ch-- == 0)
290 return i;
291 cnt++;
292 }
293 if (n != 1 && n != 2 && i >= 127)
294 break;
295 }
296 /* 見つからなかったのでもいっぺん */
297 assert(cnt > 0);
298 ch %= cnt;
299 for (i = 0; i < 256; i++)
300 if (kcls[n].map[i])
301 {
302 if (ch-- == 0)
303 return i;
304 }
305 assert(!"not matched");
306 return 0;
307 }
308
309 /* bitwise key をセット */
310 static
311 void
312 key_set64(struct KEY *key64,
313 int n,
314 unsigned k,
315 unsigned vk,
316 unsigned sk)
317 {
318 int i, j;
319 if (!((vk | sk) & 0x7F))
320 return;
321
322 for (i = 0; i < 7; i++)
323 {
324 if (n == 7 && i < N_STRIDE) continue;
325 if (sk & (1 << i))
326 {
327 /* セット */
328 int o = tr_pc1[n][6 - i] - 1;
329 if (o < 28)
330 {
331 assert(o >= 0);
332 for (j = 0; j < N_ALU; j++)
333 key64->k[0][0][o].a[j]
334 = key64->k[0][1][o].a[j]
335 = -!!(k & (1 << i));
336 }
337 else
338 {
339 assert(o >= 28);
340 assert(o < 56);
341 for (j = 0; j < N_ALU; j++)
342 key64->k[1][0][o - 28].a[j]
343 = key64->k[1][1][o - 28].a[j]
344 = -!!(k & (1 << i));
345 }
346 }
347 else if (vk & (1 << i))
348 {
349 /* 反転 */
350 int o = tr_pc1[n][6 - i] - 1;
351 if (o < 28)
352 {
353 assert(o >= 0);
354 for (j = 0; j < N_ALU; j++)
355 key64->k[0][0][o].a[j]
356 = key64->k[0][1][o].a[j]
357 = ~key64->k[0][0][o].a[j];
358 }
359 else
360 {
361 assert(o >= 28);
362 assert(o < 56);
363 for (j = 0; j < N_ALU; j++)
364 key64->k[1][0][o - 28].a[j]
365 = key64->k[1][1][o - 28].a[j]
366 = ~key64->k[1][0][o - 28].a[j];
367 }
368 }
369 }
370 }
371
372 /* 指定されたクラスの開始値にリセット
373 直前の文字のクラスに縛られる */
374 int
375 key_reset(int n)
376 {
377 if (n >= 8)
378 return 1;
379 if (n == 7)
380 {
381 key[7] = 0;
382 return 1;
383 }
384
385 /* 0-2 文字目はランダムに決める
386 3 文字目以降は初期値に */
387 if (n >= 3)
388 key[n] = key_set(n, 0);
389 else
390 key[n] = key_set(n, rand());
391
392 #if DEBUG>=3
393 printf("key[%d]=%02X ncls=%04X\n", n, key[n], kcls[n].map[key[n]]);
394 #endif
395
396 /* セットされた文字を元に、次キャラの文字クラスを決める */
397 key_make_map(n);
398
399 return key_reset(n + 1);
400 }
401
402 /* 指定された鍵空間の中で、キーをひとつ進める
403 安全にインクリメントできた場合 true を返す */
404 static
405 int
406 key_inc(int n)
407 {
408 if (n >= 8)
409 return 0;
410 else if (n == 7)
411 {
412 /* 最後のバイト */
413 key[7] = (key[7] + (1 << N_STRIDE)) & 0x7F;
414 if (key[7]) return 1;
415 else return 0;
416 }
417 else if (key_inc(n + 1)
418 /*
419 && key_inc(n + 1)
420 && key_inc(n + 1)
421 && key_inc(n + 1)*/
422 )
423 return 1;
424
425 /* Salt はインクリメントしない約束にする */
426 if (n == 1 || n == 2)
427 return 1;
428
429 #if DEBUG>=3
430 printf("key_inc(n=%d,ck=%02X)\n", n, key[n]);
431 #endif
432
433 #if USE_DT
434 /* 辞書語はインクリメントしていい約束にする */
435 if (3 <= n && n < 7 && kd[n - 3])
436 {
437 if ((key[n - 3] & 0x7F) == ((kd[n - 3] + 1)->c[0] & 0x7F)
438 && (key[n - 2] & 0x7F) == ((kd[n - 3] + 1)->c[1] & 0x7F)
439 && (key[n - 1] & 0x7F) == ((kd[n - 3] + 1)->c[2] & 0x7F))
440 {
441 memcpy(&key[n - 3], &(++kd[n - 3])->c[0], 4);
442 #if DEBUG>=2
443 printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
444 kd[n - 3]->c[0], kd[n - 3]->c[1], kd[n - 3]->c[2], kd[n - 3]->c[3],
445 kd[n - 3]->c[0], kd[n - 3]->c[1], kd[n - 3]->c[2], kd[n - 3]->c[3]);
446 #endif
447 return 1;
448 }
449 else
450 {
451 return 0;
452 }
453 }
454 else if (2 <= n && n < 6 && kd[n - 2])
455 {
456 if ((key[n - 2] & 0x7F) == ((kd[n - 2] + 1)->c[0] & 0x7F)
457 && (key[n - 1] & 0x7F) == ((kd[n - 2] + 1)->c[1] & 0x7F))
458 {
459 memcpy(&key[n - 2], &(++kd[n - 2])->c[0], 4);
460 #if DEBUG>=2
461 printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
462 kd[n - 2]->c[0], kd[n - 2]->c[1], kd[n - 2]->c[2], kd[n - 2]->c[3],
463 kd[n - 2]->c[0], kd[n - 2]->c[1], kd[n - 2]->c[2], kd[n - 2]->c[3]);
464 #endif
465 return 1;
466 }
467 else
468 {
469 return 0;
470 }
471 if (kd[n - 2]->c[0] == key[n - 2])
472 return 1;
473 else
474 return 0;
475 }
476 else if (1 <= n && n < 5 && kd[n - 1])
477 {
478 unsigned c2 = kd[n - 1]->c[0];
479 if ((0x81 <= c2 && c2 <= 0x9F)
480 || (0xE0 <= c2 && c2 <= 0xFC))
481 {
482 kd[n - 1] = NULL;
483 #if 0
484 if (!(n == 1 && n == 2))
485 key[n] &= 0x7F;
486 if (!(n == 2 && n == 3))
487 key[n - 1] &= 0x7F;
488 #endif
489 key_make_map(n - 1);
490 }
491 else if ((key[n - 1] & 0x7F) == ((kd[n - 1] + 1)->c[0] & 0x7F))
492 {
493 memcpy(&key[n - 1], &(++kd[n - 1])->c[0], 4);
494 #if DEBUG>=2
495 printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
496 kd[n - 1]->c[0], kd[n - 1]->c[1], kd[n - 1]->c[2], kd[n - 1]->c[3],
497 kd[n - 1]->c[0], kd[n - 1]->c[1], kd[n - 1]->c[2], kd[n - 1]->c[3]);
498 #endif
499 return 1;
500 }
501 else
502 {
503 return 0;
504 }
505 #if 0
506 if (kd[n - 1]->c[0] == key[n - 1])
507 return 1;
508 else
509 return 0;
510 #endif
511 }
512 else if (n < 4 && kd[n])
513 {
514 if (0 && kd[n]->c[0] == key[n])
515 return 1;
516 kd[n] = NULL;
517 #if 0
518 if (!(n == 1 || n == 2))
519 key[n] &= 0x7F;
520 #endif
521 }
522 #endif
523
524 /* 実際に増やしてみる */
525 assert(n >= 3);
526 for (;;)
527 {
528 if (n <= 3
529 && !(key[n] & 0x80)
530 && kcls[n].map[key[n] ^ 0x80] & (KCLS_DT0))
531 {
532 /* 半角カタカナの1バイト目 */
533 key[n] ^= 0x80;
534 }
535 else
536 {
537 key[n] = (key[n] & 0x7F) + 1;
538 if (key[n] >= 0x80)
539 return 0;
540 }
541
542 if (kcls[n].map[key[n]])
543 {
544 key_make_map(n);
545 key_reset(n + 1);
546 return 1;
547 }
548 }
549 while (++key[n] < 0x80)
550 {
551 if (kcls[n].map[key[n]])
552 {
553 key_make_map(n);
554 key_reset(n + 1);
555 return 1;
556 }
557 }
558 return 0;
559 }
560
561 /* 鍵を完全にリセットする
562 Saltもセットし直す */
563 static
564 void
565 key_init()
566 {
567 int i, j;
568
569 #if USE_DT
570 /* 辞書を、インデクスを作りながらマップにはめこんで逝く
571 辞書はコード順昇順に並んでるものとする */
572 for (i = 0; i < dtcnt; i++)
573 {
574 unsigned c = dt[i].c[0];
575
576 assert(dt[i].c[0]
577 && dt[i].c[1]
578 && dt[i].c[2]
579 && dt[i].c[3]);
580
581 /* BSD 鯖でしにそうな文字は残念ながら除外 */
582 assert((dt[i].c[0] & 0x7F)
583 && (dt[i].c[1] & 0x7F)
584 && (dt[i].c[2] & 0x7F)
585 && (dt[i].c[3] & 0x7F));
586
587 /* インデクス */
588 if (!dtidx[c])
589 dtidx[c] = &dt[i];
590
591 if ((0x81 <= c && c <= 0x9F)
592 || (0xE0 <= c && c <= 0xFC))
593 {
594 /* 全角なので、2バイトきまった時点で立てる */
595 cp932[256 * c + dt[i].c[1]] |= KCLS_DT1;
596 }
597 else if (0xA1 <= c && c <= 0xDF)
598 {
599 /* 半角カナ */
600 for (j = 0; j < 256; j++)
601 cp932[256 * c + j] |= KCLS_DT0;
602 }
603 }
604 /* ケツ、ちうか番人 */
605 dtidx[0x100] = &dt[i];
606 #endif
607
608 key[8] = 0;
609
610 /* 初期マップを組む */
611 for (i = 0; i < 256; i++)
612 {
613 unsigned bm = 0;
614 kcls[0].map[i] = 0;
615 for (j = 0; j < 256; j++)
616 bm |= cp932[256 * i + j];
617 kcls[0].map[i] = bm & (KCLS_AN | KCLS_KA | KCLS_K1
618 | KCLS_DT0
619 );
620 if (i >= 128)
621 kcls[0].map[i - 128] |= kcls[0].map[i];
622 }
623
624 key_reset(0);
625 }
626
627 /***************************************************************
628 *
629 * Salt のセット
630 * オペランドのオフセットを書き換えて回ってるので注意
631 *
632 */
633
634 #if N_STRIDE == 6
635 #define C(c,i,j,o) (*(int8_t *)((c) + (loo - crypt64_sta) + los[6 * (i) + (j) + (o)]))
636 #elif N_STRIDE == 7
637 #define C(c,i,j,o) (*(int32_t *)((c) + (loo - crypt64_sta) + los[6 * (i) + (j) + (o)]))
638 #endif
639
640 void
641 set_salt(signed char *code,
642 unsigned char const *k)
643 {
644 int i, j;
645
646 for (i = 0; i < 2; i++)
647 {
648 unsigned s = k[1 + i] & 255;
649 if (s > 'z')
650 s = 0;
651 else if (s >= 'a')
652 s = s - 'a' + 2 + 10 + 26;
653 else if (s >= 'A')
654 s = s - 'A' + 2 + 10;
655 else if (s >= '.')
656 s = s - '.';
657 else
658 s = 0;
659
660 #if DEBUG>=1
661 printf("Salt %d:%3o\n", i, s & 63);
662 #endif
663 for (j = 0; j < 6; j++)
664 {
665 #if DEBUG>=2
666 //printf("Salt %d:%d %+3d:%+3d",
667 printf("Salt %d:%d %08lX:%08lX",
668 i, j,
669 C(code, i, j, 0),
670 C(code, i, j, 24));
671 #endif
672 if (s & (1 << j))
673 {
674 C(code, i, j, 0) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16);
675 C(code, i, j, 24) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16);
676 }
677 else
678 {
679 C(code, i, j, 0) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16);
680 C(code, i, j, 24) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16);
681 }
682 C(code, i, j, 12) = sizeof(WS_T) * (((4 * i + j + 7) & 31) - 16);
683 C(code, i, j, 36) = sizeof(WS_T) * (((4 * i + j + 23) & 31) - 16);
684 #if DEBUG>=2
685 //printf(" => %+3d:%+3d\n",
686 printf(" => %08lX:%08lX\n",
687 C(code, i, j, 0),
688 C(code, i, j, 24));
689 #endif
690 }
691 }
692 }
693
694 static
695 unsigned
696 usec()
697 {
698 #if !defined(WIN32)
699 struct timeval tv;
700 gettimeofday(&tv, NULL);
701 return 100 * tv.tv_sec + (tv.tv_usec / 10000);
702 #else
703 struct timeb tm;
704 ftime(&tm);
705 return 100 * tm.time + tm.millitm / 10;
706 #endif
707 }
708
709 static
710 int
711 log_printf(FILE *ofp, char const *fmt, ...)
712 {
713 int r;
714 va_list ap;
715 va_start(ap, fmt);
716 vfprintf(stdout, fmt, ap);
717 r = vfprintf(ofp, fmt, ap);
718 va_end(ap);
719 if (r > 0)
720 return r;
721 perror("log_printf");
722 exit(errno);
723 }
724
725 /***************************************************************
726 *
727 * メインループとか
728 *
729 */
730
731 /* 定数項 */
732 #if N_STRIDE == 7
733 static SLICE const sk6[N_STRIDE] =
734 {
735 {0xAAAAAAAAUL, 0xAAAAAAAAUL, 0xAAAAAAAAUL, 0xAAAAAAAAUL},
736 {0xCCCCCCCCUL, 0xCCCCCCCCUL, 0xCCCCCCCCUL, 0xCCCCCCCCUL},
737 {0xF0F0F0F0UL, 0xF0F0F0F0UL, 0xF0F0F0F0UL, 0xF0F0F0F0UL},
738 {0xFF00FF00UL, 0xFF00FF00UL, 0xFF00FF00UL, 0xFF00FF00UL},
739 {0xFFFF0000UL, 0xFFFF0000UL, 0xFFFF0000UL, 0xFFFF0000UL},
740 {0x00000000UL, 0xFFFFFFFFUL, 0x00000000UL, 0xFFFFFFFFUL},
741 {0x00000000UL, 0x00000000UL, 0xFFFFFFFFUL, 0xFFFFFFFFUL},
742 };
743 #elif N_STRIDE == 6
744 static SLICE const sk6[N_STRIDE] =
745 {
746 {0xAAAAAAAAUL, 0xAAAAAAAAUL},
747 {0xCCCCCCCCUL, 0xCCCCCCCCUL},
748 {0xF0F0F0F0UL, 0xF0F0F0F0UL},
749 {0xFF00FF00UL, 0xFF00FF00UL},
750 {0xFFFF0000UL, 0xFFFF0000UL},
751 {0x00000000UL, 0xFFFFFFFFUL},
752 };
753 #endif
754
755 ALIGN_PREFIX(16) struct KEY key64 ALIGN_SUFFIX(16);
756 ALIGN_PREFIX(16) struct PARAM param64 ALIGN_SUFFIX(16);
757
758 int
759 main(int argc, char *argv[])
760 {
761 int i;
762 int mincnt;
763 signed char *code = NULL;
764 FILE *ofp;
765 FILE *sfp; /* scoreboard */
766 struct ITREE *root_expr;
767 int n_iter;
768 int cr;
769
770 int xhash_loaded;
771
772 #define N_TS 4
773 struct
774 {
775 unsigned t;
776 int c;
777 } ts[N_TS];
778
779 #if 0
780 if (argc < 2)
781 {
782 fprintf(stderr, "式きぼんぬ\n");
783 return 1;
784 }
785 #endif
786
787 assert((1 << N_STRIDE) == N_ALU * ALU_BITS);
788
789 /* t[16] は、内部演算で使用する、all 1 が入っている */
790 for (i = 0; i < N_ALU; i++)
791 param64.t[16].a[i] = -1;
792
793 /* 固定キーのコピー */
794 for (i = 0; i < N_STRIDE; i++)
795 {
796 int o = tr_pc1[7][6 - i] - 1;
797 if (o < 28)
798 {
799 key64.k[0][0][o] = key64.k[0][1][o] = sk6[i];
800 }
801 else
802 {
803 o -= 28;
804 key64.k[1][0][o] = key64.k[1][1][o] = sk6[i];
805 }
806 }
807
808 /* キースケジュールをここに押し込めておく
809 従来は crypt64.S 内で完結するように引いていた */
810 for (i = 0; i < 28; i++)
811 key64.ks[i].a[0] = sizeof(WS_T) * ks_ls[i];
812
813 /* タゲ読み込み */
814 root_expr = expr_parse("target.txt");
815
816 /* コードを生成・展開 */
817 sfp = scoreboard_open();
818 fwrite(crypt64_sta, 1, crypt64_end - crypt64_sta, sfp); /* prologue */
819 synth_synthesize(sfp, root_expr);
820 fwrite(crypt64_ep, 1, crypt64_ep_end - crypt64_ep, sfp); /* epilogue */
821
822 /* コードをメモリに貼り付ける */
823 code = scoreboard_map(sfp);
824
825 /* キーの初期化 */
826 srand(time(NULL));
827 key_init();
828 set_salt(code, key);
829 for (i = 0; i < 8; i++)
830 key_set64(&key64, i, okey[i] = key[i], 0, 0x7F);
831
832 #if DEBUG>=1
833 printf("key=%p param=%p\n", &key64, &param64);
834 #endif
835 assert(!((ptrdiff_t)&key64 & (sizeof(WS_T) - 1)));
836 assert(!((ptrdiff_t)&param64 & (sizeof(WS_T) - 1)));
837
838 if ((ofp = fopen("log.txt", "at")) == NULL)
839 {
840 perror("log.txt");
841 return errno;
842 }
843
844 setvbuf(ofp, NULL, _IONBF, BUFSIZ); /* XXX MSVCRT では _IOLBF が期待通りに動作しない */
845
846 for (i = 0; i < N_TS; i++)
847 ts[i].t = ts[i].c = 0;
848
849 mincnt = 0x7FFFFFFF;
850 n_iter = 0;
851 cr = 0;
852 /* 探索ループだぞっと */
853 for (;;)
854 {
855 int32_t cnt;
856 int k, kk;
857
858 /* 鍵のセット */
859 for (i = 0; i < 8; i++)
860 {
861 key_set64(&key64, i, key[i], key[i] ^ okey[i], 0);
862 okey[i] = key[i];
863 }
864
865 /* 呼ぶ!
866 LR 初期化は、サブモジュール内で行うべし
867 FASTCALL に準じた呼び出しのため、
868 ホントはいろいろレジスタが破壊されるハズ…なんだが。 */
869 cnt = CALL_CRYPT64(code, key64.k, param64.lr);
870
871 #if DEBUG>=1
872 if (mincnt > cnt && cnt > 0)
873 {
874 mincnt = cnt;
875 if (cr)
876 fprintf(stderr, "\n");
877 cr = 0;
878 fprintf(stderr, "cycle=%d\n", (int)cnt);
879 }
880 #endif
881
882 /* ヒットしたときの処理 */
883 xhash_loaded = 0;
884 for (kk = 0; kk < N_ALU; kk++)
885 {
886 ALU_T t;
887 if (!(kk & 1))
888 xhash_loaded = 0;
889
890 t = param64.t[31].a[kk];
891 if (!t)
892 continue;
893
894 for (k = 0; k < ALU_BITS; k++)
895 {
896 static uint64_t xhash[64];
897 char hash[16];
898 unsigned char buf[32];
899
900 if (!(t & ((ALU_T)1 << k)))
901 continue;
902
903 /* 転置 */
904 if (!xhash_loaded)
905 {
906 CALL_TR64(&param64.lr[0][0].q[kk >> 1], xhash); /* XXX x64 ではダメ */
907 xhash_loaded = 1;
908 }
909
910 /* 辞書を調べる */
911 if (!synth_dict_ishit(param64.hit, kk, k, xhash[(ALU_BITS * kk + k) & 0x3F]))
912 continue;
913
914 for (i = 1; i < 11; i++)
915 {
916 unsigned c = 0;
917 c = (xhash[(ALU_BITS * kk + k) & 63] >> (6 * (i - 1))) & 0x3F; /* XXX */
918 hash[i - 1] = C64[c];
919 }
920 hash[10] = 0;
921
922 memcpy(buf, key, 32);
923 buf[8] = buf[9] = 0;
924 buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k;
925 if (translate(buf, 0, 1))
926 {
927 if (cr)
928 fprintf(stderr, "\n");
929 cr = 0;
930 log_printf(ofp,
931 "◆%s #%-10.10s(%02X %02X %02X %02X %02X %02X %02X %02X/%02X)\n",
932 hash,
933 buf,
934 buf[0], buf[1], buf[2], buf[3],
935 buf[4], buf[5], buf[6], buf[7],
936 buf[8]);
937 }
938 else
939 {
940 #if DEBUG>=1
941 if (cr)
942 fprintf(stderr, "\n");
943 cr = 0;
944 log_printf(ofp,
945 "◆%s (%02X %02X %02X %02X %02X %02X %02X %02X )\n",
946 hash,
947 buf[0], buf[1], buf[2], buf[3],
948 buf[4], buf[5], buf[6], buf[7]);
949 #endif
950 }
951 }
952 }
953
954 if (++n_iter - ts[0].c >= 8192)
955 {
956 int t = usec();
957 if (ts[N_TS - 1].c)
958 {
959 int a = (100 << N_STRIDE) * (n_iter - ts[N_TS - 1].c) / (t - ts[N_TS - 1].t);
960 fprintf(stderr,
961 "%8d.%03d(ktrips/sec)\r",
962 a / 1000,
963 a % 1000);
964 cr++;
965 }
966 for (i = N_TS - 1; i >= 1; i--)
967 ts[i] = ts[i - 1];
968 ts[0].c = n_iter;
969 ts[0].t = t;
970 for (i = 1; i < N_TS; i++)
971 if (ts[i].c)
972 break;
973 else
974 ts[i] = ts[i - 1];
975 }
976 #if 1
977 if (!key_inc(3))
978 {
979 #if DEBUG>=2
980 printf("********************************\n");
981 #endif
982 key_reset(0);
983 set_salt(code, key);
984 for (i = 0; i < 8; i++)
985 key_set64(&key64, i, okey[i] = key[i], 0, 0x7F);
986 }
987 #endif
988 }
989
990 return 0;
991 }
992
993 /*
994 * Local Variables:
995 * tab-width: 4
996 * End:
997 *
998 * EOF */

Properties

Name Value
svn:eol-style native

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26