module ia32/elf/begin.sts module ia32/float/float.sts module cipher.sts module keygen.sts module freq.sts [ sd 0 swap drop ] defword nicedist 1 float_iload 4 float_iload float_div exit defword calcdist ; distance from ideal as sqrt sum square diff top 1a - as calcdist.textfr local calcdist.fr 0 do dup 1a = until dup word_size mul as calcdist.i calcdist.i calcdist.fr + @ float_fload calcdist.i calcdist.textfr + @ float_fload float_sub float_fstore dup float_fload float_fload float_mul float_fstore calcdist.i calcdist.fr + ! 1 + od drop 0 do dup 19 = until swap float_fload swap float_fload float_add float_fstore swap 1 + od drop float_fload float_sqrt nicedist float_less exit defword checktext as checktext.length local checktext.text ; Count frequencies: ; 26 latin letters: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 local checktext.fr ; count how much of each letter is in text: 0 as checktext.count checktext.length do 1 - dup word_size mul checktext.text + @ dup dup 'z' > 0 = swap 'a' < 0 = mul if dup 'z' swap - word_size mul checktext.fr + dup @ 1 + swap ! checktext.count 1 + as checktext.count fi dup dup 'Z' > 0 = swap 'A' < 0 = mul if dup 'Z' swap - word_size mul checktext.fr + dup @ 1 + swap ! checktext.count 1 + as checktext.count fi drop dup 0 = untilod drop ; ZERO DIVISION SHALL NOT PASS checktext.count 0 = if drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop drop 0 exit fi ; normalize: 0 do dup 1a = until dup word_size mul checktext.fr + dup @ float_iload checktext.count float_iload float_div float_fstore swap ! 1 + od drop 1a print_stack newline sys_write ; Decide if text is real: freq_eng calcdist if 1 else 0 fi ; Remove frequencies from stack: sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd sd exit set_entry float_init ; this is program with floats ; read file into stack 0 do sys_read 0 = until swap 1 + od drop as length local ciphertext 0 ; initial key is empty do ; generate next key to try keygen as keylen local key ; decipher text (length is the same as for ciphertext) keylen 1 - length do 1 - as textpos local pos textpos word_size mul ciphertext + @ key keylen pos cipher swap textpos dup 0 = untilod drop drop local plaintext ; check deciphering attempt, exit if Ok or keylen = max (2) keylen 2 = if eeeee else length checktext fi dup until drop ; else remove the text from stack and place keylen back 0 do dup length = until swap drop 1 + od drop keylen od as langcode ; output language langcode 1 = if 'e' sys_write_err 'n' sys_write_err 'g' sys_write_err 'l' sys_write_err 'i' sys_write_err 's' sys_write_err 'h' sys_write_err fi langcode 2 = if 'd' sys_write_err 'u' sys_write_err 't' sys_write_err 'c' sys_write_err 'h' sys_write_err fi langcode 3 = if 'g' sys_write_err 'e' sys_write_err 'r' sys_write_err 'm' sys_write_err 'a' sys_write_err 'n' sys_write_err fi langcode 4 = if 'f' sys_write_err 'r' sys_write_err 'e' sys_write_err 'n' sys_write_err 'c' sys_write_err 'h' sys_write_err fi langcode 5 = if 's' sys_write_err 'p' sys_write_err 'a' sys_write_err 'n' sys_write_err 'i' sys_write_err 's' sys_write_err 'h' sys_write_err fi langcode 6 = if 'i' sys_write_err 't' sys_write_err 'a' sys_write_err 'l' sys_write_err 'i' sys_write_err 'a' sys_write_err 'n' sys_write_err fi langcode eeeee = if 'e' sys_write_err 'r' sys_write_err 'r' sys_write_err 'o' sys_write_err 'r' sys_write_err fi ; output text length do 1 - dup word_size mul plaintext + @ sys_write dup 0 = untilod sys_exit module ia32/elf/end.sts