#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
double RAND_MAX;
int /*<<< orphan*/ bifidDecipher(char *, int, char *, char *, int);
int /*<<< orphan*/ exchange2letters(char *);
double exp(double);
int /*<<< orphan*/ free(char *);
char *malloc(int);
double rand();
double scoreTextQgram(char *, int);
int /*<<< orphan*/ strcpy(char *, char *);
float bifidCrack(char *text, int len, char *bestKey, int period) {
  int i, j, count;
  float T;
  char temp, *deciphered = malloc(sizeof(char) * (len + 1));
  char testKey[26];
  char maxKey[26];
  double prob, dF, maxscore, score;
  double bestscore;
  strcpy(maxKey, bestKey);
  bifidDecipher(maxKey, period, text, deciphered, len);
  maxscore = scoreTextQgram(deciphered, len);
  bestscore = maxscore;
  for (T = 20; T >= 0; T -= 0.1) {
    for (count = 0; count < 10000; count++) {
      strcpy(testKey, maxKey);
      exchange2letters(testKey);
      bifidDecipher(testKey, period, text, deciphered, len);
      score = scoreTextQgram(deciphered, len);
      dF = score - maxscore;
      if (dF >= 0) {
        maxscore = score;
        strcpy(maxKey, testKey);
      } else if (T > 0) {
        prob = exp(dF / T);
        if (prob > 1.0 * rand() / RAND_MAX) {
          maxscore = score;
          strcpy(maxKey, testKey);
        }
      }
      if (maxscore > bestscore) {
        bestscore = maxscore;
        strcpy(bestKey, maxKey);
      }
    }
  }
  free(deciphered);
  return bestscore;
}


x86 assembly (clang, -O0):
<bifidCrack>:
push   %rbp
mov    %rsp,%rbp
sub    $0xb0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
cltq
shl    $0x0,%rax
mov    %eax,%edi
call   1060 <malloc@plt>
mov    %rax,-0x38(%rbp)
lea    -0x80(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1050 <strcpy@plt>
lea    -0x80(%rbp),%rdi
mov    -0x1c(%rbp),%esi
mov    -0x8(%rbp),%rdx
mov    -0x38(%rbp),%rcx
mov    -0xc(%rbp),%r8d
call   1080 <bifidDecipher@plt>
mov    -0x38(%rbp),%rdi
mov    -0xc(%rbp),%esi
call   1090 <scoreTextQgram@plt>
movsd  %xmm0,-0x98(%rbp)
ff
movsd  -0x98(%rbp),%xmm0
ff
movsd  %xmm0,-0xa8(%rbp)
ff
movss  0xdff(%rip),%xmm0
movss  %xmm0,-0x2c(%rbp)
movss  -0x2c(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jb     13c7 <bifidCrack+0x247>
movl   $0x0,-0x28(%rbp)
cmpl   $0x2710,-0x28(%rbp)
jge    139f <bifidCrack+0x21f>
lea    -0x60(%rbp),%rdi
lea    -0x80(%rbp),%rsi
call   1050 <strcpy@plt>
lea    -0x60(%rbp),%rdi
call   1040 <exchange2letters@plt>
lea    -0x60(%rbp),%rdi
mov    -0x1c(%rbp),%esi
mov    -0x8(%rbp),%rdx
mov    -0x38(%rbp),%rcx
mov    -0xc(%rbp),%r8d
call   1080 <bifidDecipher@plt>
mov    -0x38(%rbp),%rdi
mov    -0xc(%rbp),%esi
call   1090 <scoreTextQgram@plt>
movsd  %xmm0,-0xa0(%rbp)
ff
movsd  -0xa0(%rbp),%xmm0
ff
subsd  -0x98(%rbp),%xmm0
ff
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x90(%rbp),%xmm0
ff
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     12bc <bifidCrack+0x13c>
movsd  -0xa0(%rbp),%xmm0
ff
movsd  %xmm0,-0x98(%rbp)
ff
lea    -0x80(%rbp),%rdi
lea    -0x60(%rbp),%rsi
call   1050 <strcpy@plt>
jmp    1359 <bifidCrack+0x1d9>
movss  -0x2c(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jbe    1354 <bifidCrack+0x1d4>
movsd  -0x90(%rbp),%xmm0
ff
movss  -0x2c(%rbp),%xmm1
cvtss2sd %xmm1,%xmm1
divsd  %xmm1,%xmm0
call   1070 <exp@plt>
movsd  %xmm0,-0x88(%rbp)
ff
movsd  -0x88(%rbp),%xmm0
ff
movsd  %xmm0,-0xb0(%rbp)
ff
mov    $0x0,%al
call   10a0 <rand@plt>
movaps %xmm0,%xmm2
movsd  -0xb0(%rbp),%xmm0
ff
movsd  0xcf7(%rip),%xmm1
mulsd  %xmm2,%xmm1
mov    0x2cc4(%rip),%rax
divsd  (%rax),%xmm1
ucomisd %xmm1,%xmm0
jbe    134f <bifidCrack+0x1cf>
movsd  -0xa0(%rbp),%xmm0
ff
movsd  %xmm0,-0x98(%rbp)
ff
lea    -0x80(%rbp),%rdi
lea    -0x60(%rbp),%rsi
call   1050 <strcpy@plt>
jmp    1354 <bifidCrack+0x1d4>
jmp    1359 <bifidCrack+0x1d9>
movsd  -0x98(%rbp),%xmm0
ff
ucomisd -0xa8(%rbp),%xmm0
ff
jbe    138c <bifidCrack+0x20c>
movsd  -0x98(%rbp),%xmm0
ff
movsd  %xmm0,-0xa8(%rbp)
ff
mov    -0x18(%rbp),%rdi
lea    -0x80(%rbp),%rsi
call   1050 <strcpy@plt>
jmp    1391 <bifidCrack+0x211>
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    121e <bifidCrack+0x9e>
jmp    13a4 <bifidCrack+0x224>
movss  -0x2c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xc53(%rip),%xmm1
subsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x2c(%rbp)
jmp    1206 <bifidCrack+0x86>
mov    -0x38(%rbp),%rdi
call   1030 <free@plt>
movsd  -0xa8(%rbp),%xmm0
ff
cvtsd2ss %xmm0,%xmm0
add    $0xb0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<bifidCrack>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x88,%rsp
mov    %ecx,%r12d
mov    %rdx,%r15
mov    %esi,%ebx
mov    %rdi,%r14
lea    0x1(%rbx),%edi
call   1060 <malloc@plt>
mov    %rax,%rbp
lea    0x40(%rsp),%r13
mov    %r13,%rdi
mov    %r15,0x38(%rsp)
mov    %r15,%rsi
call   1050 <strcpy@plt>
mov    %r13,%rdi
mov    %r12d,0x24(%rsp)
mov    %r12d,%esi
mov    %r14,%r12
mov    %r14,%rdx
mov    %rbp,%rcx
mov    %ebx,%r8d
call   1080 <bifidDecipher@plt>
mov    %rbp,%rdi
mov    %ebx,%esi
call   1090 <scoreTextQgram@plt>
movss  0xe16(%rip),%xmm1
lea    0x60(%rsp),%r14
movsd  %xmm0,0x10(%rsp)
movsd  %xmm0,0x8(%rsp)
jmp    1222 <bifidCrack+0xa2>
nopl   (%rax)
movsd  0x28(%rsp),%xmm0
addsd  0xdfa(%rip),%xmm0
xorps  %xmm1,%xmm1
cvtsd2ss %xmm0,%xmm1
ucomiss 0xde8(%rip),%xmm1
jb     1327 <bifidCrack+0x1a7>
movss  %xmm1,0x20(%rsp)
xorps  %xmm0,%xmm0
cvtss2sd %xmm1,%xmm0
movsd  %xmm0,0x28(%rsp)
mov    $0x2710,%r15d
jmp    1246 <bifidCrack+0xc6>
nopl   (%rax)
add    $0xffffffff,%r15d
je     1200 <bifidCrack+0x80>
mov    %r14,%rdi
mov    %r13,%rsi
call   1050 <strcpy@plt>
mov    %r14,%rdi
call   1040 <exchange2letters@plt>
mov    %r14,%rdi
mov    0x24(%rsp),%esi
mov    %r12,%rdx
mov    %rbp,%rcx
mov    %ebx,%r8d
call   1080 <bifidDecipher@plt>
mov    %rbp,%rdi
mov    %ebx,%esi
call   1090 <scoreTextQgram@plt>
movaps %xmm0,%xmm3
movsd  0x8(%rsp),%xmm2
subsd  %xmm2,%xmm0
ucomisd 0xd83(%rip),%xmm0
jae    12e0 <bifidCrack+0x160>
movss  0x20(%rsp),%xmm1
ucomiss 0xd68(%rip),%xmm1
jbe    12f7 <bifidCrack+0x177>
divsd  0x28(%rsp),%xmm0
movsd  %xmm3,0x18(%rsp)
call   1070 <exp@plt>
movsd  %xmm0,0x30(%rsp)
xor    %eax,%eax
call   10a0 <rand@plt>
movsd  0x18(%rsp),%xmm3
movsd  0x8(%rsp),%xmm2
mov    0x2d19(%rip),%rax
divsd  (%rax),%xmm0
movsd  0x30(%rsp),%xmm1
ucomisd %xmm0,%xmm1
jbe    12f7 <bifidCrack+0x177>
nop
movsd  %xmm3,0x18(%rsp)
mov    %r13,%rdi
mov    %r14,%rsi
call   1050 <strcpy@plt>
movsd  0x18(%rsp),%xmm2
movsd  %xmm2,0x8(%rsp)
ucomisd 0x10(%rsp),%xmm2
jbe    1240 <bifidCrack+0xc0>
mov    0x38(%rsp),%rdi
mov    %r13,%rsi
call   1050 <strcpy@plt>
movsd  0x8(%rsp),%xmm0
movsd  %xmm0,0x10(%rsp)
jmp    1240 <bifidCrack+0xc0>
mov    %rbp,%rdi
call   1030 <free@plt>
movsd  0x10(%rsp),%xmm0
cvtsd2ss %xmm0,%xmm0
add    $0x88,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@RAND_MAX = global double 0.000000e+00
define float @bifidCrack(i8* %0, i32 %1, i8* %2, i32 %3) {
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i8*
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca float
%13 = alloca i8
%14 = alloca i8*
%15 = alloca [26 x i8]
%16 = alloca [26 x i8]
%17 = alloca double
%18 = alloca double
%19 = alloca double
%20 = alloca double
%21 = alloca double
store i8* %0, i8** %5
store i32 %1, i32* %6
store i8* %2, i8** %7
store i32 %3, i32* %8
%22 = load i32, i32* %6
%23 = add nsw i32 %22, 1
%24 = sext i32 %23 to i64
%25 = mul i64 1, %24
%26 = trunc i64 %25 to i32
%27 = call i8* @malloc(i32 %26)
store i8* %27, i8** %14
%28 = getelementptr inbounds [26 x i8], [26 x i8]* %16, i64 0, i64 0
%29 = load i8*, i8** %7
%30 = call i32 @strcpy(i8* %28, i8* %29)
%31 = getelementptr inbounds [26 x i8], [26 x i8]* %16, i64 0, i64 0
%32 = load i32, i32* %8
%33 = load i8*, i8** %5
%34 = load i8*, i8** %14
%35 = load i32, i32* %6
%36 = call i32 @bifidDecipher(i8* %31, i32 %32, i8* %33, i8* %34, i32 %35)
%37 = load i8*, i8** %14
%38 = load i32, i32* %6
%39 = call double @scoreTextQgram(i8* %37, i32 %38)
store double %39, double* %19
%40 = load double, double* %19
store double %40, double* %21
store float 2.000000e+01, float* %12
br label %41
41: ; preds = %109, %4
%42 = load float, float* %12
%43 = fcmp oge float %42, 0.000000e+00
br i1 %43, label %44, label %114
44: ; preds = %41
store i32 0, i32* %11
br label %45
45: ; preds = %105, %44
%46 = load i32, i32* %11
%47 = icmp slt i32 %46, 10000
br i1 %47, label %48, label %108
48: ; preds = %45
%49 = getelementptr inbounds [26 x i8], [26 x i8]* %15, i64 0, i64 0
%50 = getelementptr inbounds [26 x i8], [26 x i8]* %16, i64 0, i64 0
%51 = call i32 @strcpy(i8* %49, i8* %50)
%52 = getelementptr inbounds [26 x i8], [26 x i8]* %15, i64 0, i64 0
%53 = call i32 @exchange2letters(i8* %52)
%54 = getelementptr inbounds [26 x i8], [26 x i8]* %15, i64 0, i64 0
%55 = load i32, i32* %8
%56 = load i8*, i8** %5
%57 = load i8*, i8** %14
%58 = load i32, i32* %6
%59 = call i32 @bifidDecipher(i8* %54, i32 %55, i8* %56, i8* %57, i32 %58)
%60 = load i8*, i8** %14
%61 = load i32, i32* %6
%62 = call double @scoreTextQgram(i8* %60, i32 %61)
store double %62, double* %20
%63 = load double, double* %20
%64 = load double, double* %19
%65 = fsub double %63, %64
store double %65, double* %18
%66 = load double, double* %18
%67 = fcmp oge double %66, 0.000000e+00
br i1 %67, label %68, label %73
68: ; preds = %48
%69 = load double, double* %20
store double %69, double* %19
%70 = getelementptr inbounds [26 x i8], [26 x i8]* %16, i64 0, i64 0
%71 = getelementptr inbounds [26 x i8], [26 x i8]* %15, i64 0, i64 0
%72 = call i32 @strcpy(i8* %70, i8* %71)
br label %95
73: ; preds = %48
%74 = load float, float* %12
%75 = fcmp ogt float %74, 0.000000e+00
br i1 %75, label %76, label %94
76: ; preds = %73
%77 = load double, double* %18
%78 = load float, float* %12
%79 = fpext float %78 to double
%80 = fdiv double %77, %79
%81 = call double @exp(double %80)
store double %81, double* %17
%82 = load double, double* %17
%83 = call double (...) @rand()
%84 = fmul double 1.000000e+00, %83
%85 = load double, double* @RAND_MAX
%86 = fdiv double %84, %85
%87 = fcmp ogt double %82, %86
br i1 %87, label %88, label %93
88: ; preds = %76
%89 = load double, double* %20
store double %89, double* %19
%90 = getelementptr inbounds [26 x i8], [26 x i8]* %16, i64 0, i64 0
%91 = getelementptr inbounds [26 x i8], [26 x i8]* %15, i64 0, i64 0
%92 = call i32 @strcpy(i8* %90, i8* %91)
br label %93
93: ; preds = %88, %76
br label %94
94: ; preds = %93, %73
br label %95
95: ; preds = %94, %68
%96 = load double, double* %19
%97 = load double, double* %21
%98 = fcmp ogt double %96, %97
br i1 %98, label %99, label %104
99: ; preds = %95
%100 = load double, double* %19
store double %100, double* %21
%101 = load i8*, i8** %7
%102 = getelementptr inbounds [26 x i8], [26 x i8]* %16, i64 0, i64 0
%103 = call i32 @strcpy(i8* %101, i8* %102)
br label %104
104: ; preds = %99, %95
br label %105
105: ; preds = %104
%106 = load i32, i32* %11
%107 = add nsw i32 %106, 1
store i32 %107, i32* %11
br label %45
108: ; preds = %45
br label %109
109: ; preds = %108
%110 = load float, float* %12
%111 = fpext float %110 to double
%112 = fsub double %111, 1.000000e-01
%113 = fptrunc double %112 to float
store float %113, float* %12
br label %41
114: ; preds = %41
%115 = load i8*, i8** %14
%116 = call i32 @free(i8* %115)
%117 = load double, double* %21
%118 = fptrunc double %117 to float
ret float %118
}

LLVM IR (-O2):
@RAND_MAX = global double 0.000000e+00
define float @bifidCrack(i8* %0, i32 %1, i8* %2, i32 %3) {
%5 = alloca [26 x i8]
%6 = alloca [26 x i8]
%7 = add nsw i32 %1, 1
%8 = tail call i8* @malloc(i32 %7)
%9 = getelementptr inbounds [26 x i8], [26 x i8]* %5, i64 0, i64 0
%10 = getelementptr inbounds [26 x i8], [26 x i8]* %6, i64 0, i64 0
%11 = call i32 @strcpy(i8* %10, i8* %2)
%12 = call i32 @bifidDecipher(i8* %10, i32 %3, i8* %0, i8* %8, i32 %1)
%13 = call double @scoreTextQgram(i8* %8, i32 %1)
br label %14
14: ; preds = %4, %49
%15 = phi double [ %13, %4 ], [ %46, %49 ]
%16 = phi double [ %13, %4 ], [ %41, %49 ]
%17 = phi float [ 2.000000e+01, %4 ], [ %51, %49 ]
%18 = fcmp ogt float %17, 0.000000e+00
%19 = fpext float %17 to double
br label %20
20: ; preds = %14, %45
%21 = phi double [ %15, %14 ], [ %46, %45 ]
%22 = phi i32 [ 0, %14 ], [ %47, %45 ]
%23 = phi double [ %16, %14 ], [ %41, %45 ]
%24 = call i32 @strcpy(i8* %9, i8* %10)
%25 = call i32 @exchange2letters(i8* %9)
%26 = call i32 @bifidDecipher(i8* %9, i32 %3, i8* %0, i8* %8, i32 %1)
%27 = call double @scoreTextQgram(i8* %8, i32 %1)
%28 = fsub double %27, %23
%29 = fcmp ult double %28, 0.000000e+00
br i1 %29, label %30, label %38
30: ; preds = %20
br i1 %18, label %31, label %40
31: ; preds = %30
%32 = fdiv double %28, %19
%33 = call double @exp(double %32)
%34 = call double (...) @rand()
%35 = load double, double* @RAND_MAX
%36 = fdiv double %34, %35
%37 = fcmp ogt double %33, %36
br i1 %37, label %38, label %40
38: ; preds = %31, %20
%39 = call i32 @strcpy(i8* %10, i8* %9)
br label %40
40: ; preds = %38, %30, %31
%41 = phi double [ %23, %31 ], [ %23, %30 ], [ %27, %38 ]
%42 = fcmp ogt double %41, %21
br i1 %42, label %43, label %45
43: ; preds = %40
%44 = call i32 @strcpy(i8* %2, i8* %10)
br label %45
45: ; preds = %40, %43
%46 = phi double [ %41, %43 ], [ %21, %40 ]
%47 = add nuw nsw i32 %22, 1
%48 = icmp eq i32 %47, 10000
br i1 %48, label %49, label %20
49: ; preds = %45
%50 = fadd double %19, -1.000000e-01
%51 = fptrunc double %50 to float
%52 = fcmp ult float %51, 0.000000e+00
br i1 %52, label %53, label %14
53: ; preds = %49
%54 = call i32 @free(i8* %8)
%55 = fptrunc double %46 to float
ret float %55
}