├── DECRYPTME.txt ├── LICENSE ├── PASSWORDS.js ├── README.md ├── ServerSidePHP ├── playfair.php ├── quip.php └── vigi.php ├── UserSettings.js ├── css ├── base.css ├── jquery.orgchart.css └── normal.css ├── index.html ├── js ├── Analyze.js ├── ForceFlow.js ├── Global.js ├── Grade.js ├── Guess.js ├── MAIN.js ├── Moar.js ├── OLD_code.js ├── Student.js ├── Teacher.js ├── Test.js ├── TestCases.js ├── TestCasesAll.js ├── Under_development.js ├── WorkSpace.js ├── binary.js ├── cipher │ ├── affine.js │ ├── atbash.js │ ├── baconian.js │ ├── base58.js │ ├── base64.js │ ├── baseX.js │ ├── baudotmurray.js │ ├── bifid.js │ ├── bytearray.js │ ├── caesar.js │ ├── code39.js │ ├── coltrans.js │ ├── digraph.js │ ├── ebcdic.js │ ├── enigma │ │ ├── base.js │ │ ├── dom.js │ │ ├── enigma-sim.js │ │ ├── enigma.js │ │ ├── events.js │ │ ├── formatutil.js │ │ ├── mersene_twister.js │ │ ├── namespace.js │ │ └── random.js │ ├── friedman.js │ ├── hash.js │ ├── keymaker.js │ ├── letternumbers.js │ ├── lsb.js │ ├── maze.js │ ├── morse.js │ ├── onlinelookup.js │ ├── otp.js │ ├── playfair.js │ ├── railfence.js │ ├── romannumerals.js │ ├── rotate.js │ ├── skip.js │ ├── statistics.js │ ├── substitute.js │ ├── substitute_OLD.js │ ├── transposition.js │ ├── util.js │ ├── vigenere.js │ ├── webapp │ │ ├── viewstateparser.js │ │ └── webapp.js │ ├── weirdcrypto.js │ └── xor.js ├── fileupdownload.js ├── jquery-2.2.4.min.js ├── jquery.orgchart.js ├── manipulateString.js ├── notUglifiable.js ├── settings.js └── timer.js └── media ├── Mario_Coin.mp3 ├── Roboto-Regular.ttf ├── SCWF-current-cap.png ├── SCWF-example.gif ├── SyllabaireMandombe.jpg ├── Tengwar(Elvish).png ├── add.png ├── alienese.png ├── arrow2.png ├── arrow3.png ├── baudot-murray-code.png ├── bionicle.gif ├── braille.gif ├── code39.jpg ├── code93.png ├── copy.png ├── dancingmen.png ├── delete.png ├── emblem.ico ├── flagsemaphore.jpg ├── gallifreyenalphabet.jpg ├── gravityfalls.jpg ├── guess.jpg ├── hittitealphabet.png ├── loading.gif ├── monkcipher.jpg ├── nyctograph.jpg ├── ogham.png ├── pigpencipher.png ├── refresh.png ├── save.png ├── timesherald.jpg ├── vic_checkerboard.jpg └── vic_checkerboard_ru.jpg /PASSWORDS.js: -------------------------------------------------------------------------------- 1 | //Newlines, trailing spaces and trailing tabs will be ignored!! (tokenized on spaces) 2 | //'password','secret','pass','test','code','key' are already in the list in UserSettings.js 3 | var brute_force_dictionary_keys_extra = ` 4 | 5 | cyberlympics 6 | t0k3n 7 | token 8 | s3cr3t 9 | s3cr3ts 10 | GGoC 11 | GGoCySEA 12 | tang0 13 | Warl0ck 14 | wgcode 15 | FSociety 16 | Mark83a 17 | 18 | 19 | 20 | `; 21 | 22 | 23 | 24 | 25 | /* Other potentially interesting stuff for Cyberlympics? 26 | FSociety 27 | MUD 28 | morpheus 29 | tang0livelabs 30 | megan 31 | DarkLord 32 | Targ3t*/ 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | //Please leave this line in ;) 57 | brute_force_dictionary_keys = brute_force_dictionary_keys.concat(brute_force_dictionary_keys_extra.split(/\s*\r?\n/).filter(function(n){ return n != '' })); 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Solve Crypto With Force (SCWF) 2 | 3 | CTF tool for identifying, brute forcing and decoding encryption schemes in an automated way. 4 | 5 | [Click here](https://scwf.dima.ninja/) for the live version (use Chrome). 6 | 7 | Crypto CTF (sub)challenges can roughly be categorized as follows: 8 | 1. Weak implementation/configuration of strong cryptographic schemes (e.g. RSA based challenges) 9 | 2. Weak cryptographic cipher usage (e.g. Vigenère) 10 | 3. Obfuscation (e.g. Skip, Railfence) 11 | 4. Encodings (e.g. Base32, Morse) 12 | 13 | While case 1 is arguably the most fun to solve, cases 2 to 4 are still used in CTFs, i.e. CyberLympics. It can take a lot of time figuring out what it exactly is. This is especially true since no available tool does the identification of which cipher/encoding is used. 14 | 15 | Solve Crypto With Force (SCWF) was created in 2014 as a "scratch your own itch" to automate the identification and decryption of the above mentioned cases 2 to 4 in certain CTF's (*cough* CyberLympics). This allowed brainpower to be used for other, more fun challenges to be solved. 16 | 17 | SCWF uses statistical analysis to identify which encoding or encryption is used and grade the output using a dictionary. It will grade each output by identifying English words, links and flags. You input a challenge in the top textarea and it will make a graph in an attempt to solve it. 18 | 19 | ![alt text][example] 20 | A graph that is created within a few seconds from this example input: [2016 Internetwache CTF - crypto pirate 50](https://github.com/ctfs/write-ups-2016/tree/master/internetwache-ctf-2016/crypto/crypto-pirat-50) 21 | 22 | Currently, the following ciphers can be identified and solved fully or to a certain extent: 23 | ![alt text][currentcap] 24 | 25 | 26 | ## Getting Started 27 | 28 | [Click here](https://scwf.dima.ninja/) for the live version. 29 | 30 | For offline use: clone all and open index.html. 31 | 32 | Optional: Host /ServerSidePHP/ folder on your own server and point "var lookup_proxy_host" to your own server. 33 | 34 | Support: The code is only tested for Chrome on a 1080p normal-PPI screen. However, Firefox on Linux also seems to work reasonably well. 35 | 36 | 37 | ## Running the tests 38 | 39 | Manual testing can be done by pasting your obfuscated string or one from DECRYPTME.txt in the top textarea. 40 | 41 | Running automated tests is as easy as hitting the top-right "Test-Mode" button. Every time a new cipher is added, add one extra test case in js/TestCases.js . 42 | 43 | 44 | ## Acknowledgments 45 | 46 | For testing, brainstorming and bug reports :smile: 47 | * Hack.ERS 48 | * dotelite 49 | 50 | All other projects I borrowed code from! 51 | 52 | ## License 53 | 54 | This project is licensed under the GNU General Public License v3.0. 55 | 56 | 57 | [example]: https://github.com/DaWouw/SCWF/raw/master/media/SCWF-example.gif "Example of running SCWF" 58 | [currentcap]: https://github.com/DaWouw/SCWF/raw/master/media/SCWF-current-cap.png "Currently supported algorithms" 59 | -------------------------------------------------------------------------------- /ServerSidePHP/playfair.php: -------------------------------------------------------------------------------- 1 | )([^<]*)(?:<\/tt>)#", $find, $matches); 9 | for($i = 0; $i < 20 && $i < sizeof($matches[0]); $i+=2) { 10 | echo '"'.str_ireplace(array('',''), null, $matches[0][$i]).'|'.str_ireplace(array('',''), null, $matches[0][$i+1])."\"\n"; 11 | } 12 | } 13 | ?> 14 | -------------------------------------------------------------------------------- /ServerSidePHP/quip.php: -------------------------------------------------------------------------------- 1 | solsum(.*?);#", $find, $matches); 30 | preg_match_all('#plaintext\"\:\"([^\"]*)\"#', $find, $matches); 31 | foreach ($matches[1] as $match){ 32 | echo '"'.$match . "\"\n"; 33 | } 34 | } 35 | ?> 36 | -------------------------------------------------------------------------------- /ServerSidePHP/vigi.php: -------------------------------------------------------------------------------- 1 | $d) { 27 | 28 | $curly[$id] = curl_init(); 29 | 30 | $url = (is_array($d) && !empty($d['url'])) ? $d['url'] : $d; 31 | curl_setopt($curly[$id], CURLOPT_URL, $url); 32 | curl_setopt($curly[$id], CURLOPT_HEADER, 0); 33 | curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, 1); 34 | 35 | // post? 36 | if (is_array($d)) { 37 | if (!empty($d['post'])) { 38 | curl_setopt($curly[$id], CURLOPT_POST, 1); 39 | curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $d['post']); 40 | curl_setopt($curly[$id], CURLOPT_CONNECTTIMEOUT, 120); 41 | curl_setopt($curly[$id], CURLOPT_TIMEOUT, 120); 42 | //curl_setopt($curly[$id], CURLOPT_HTTPPROXYTUNNEL, true); 43 | //curl_setopt($curly[$id], CURLOPT_PROXY, 'http://localhost:6868'); 44 | } 45 | } 46 | 47 | // extra options? 48 | if (!empty($options)) { 49 | curl_setopt_array($curly[$id], $options); 50 | } 51 | 52 | curl_multi_add_handle($mh, $curly[$id]); 53 | } 54 | 55 | // execute the handles 56 | $running = null; 57 | do { 58 | curl_multi_exec($mh, $running); 59 | } while($running > 0); 60 | 61 | 62 | // get content and remove handles 63 | foreach($curly as $id => $c) { 64 | $result[$id] = curl_multi_getcontent($c); 65 | curl_multi_remove_handle($mh, $c); 66 | } 67 | 68 | // all done 69 | curl_multi_close($mh); 70 | 71 | return $result; 72 | } 73 | 74 | 75 | 76 | if (isset($_GET['a'])) 77 | { 78 | $from_range = isset($_GET['f']) && $_GET['f']>=2 && $_GET['f']<=14?$_GET['f']:5; 79 | $to_range = isset($_GET['t']) && $_GET['t']>=3 && $_GET['t']<=15?$_GET['t']:9; 80 | 81 | if($from_range >= $to_range) return; 82 | $diff_range = ceil(($to_range - $from_range)/BLOCK_SIZE); 83 | 84 | for($d = 0; $d < $diff_range; $d++) 85 | { 86 | $data = array(); 87 | 88 | $now_from_range = $from_range+$d*BLOCK_SIZE; 89 | $now_to_range = $from_range+($d+1)*BLOCK_SIZE; 90 | for($i = $now_from_range; $i < $to_range && $i < $now_to_range; $i++) { 91 | /*$post = array( 92 | '__EVENTTARGET' => '', 93 | '__EVENTARGUMENT' => '', 94 | '__VIEWSTATE' => '/wEPDwULLTE1OTUxODk4NzVkGAEFHl9fQ29udHJvbHNSZXF1aXJlUG9zdEJhY2tLZXlfXxYFBQtLZXlLbm93blllcwUTS2V5S25vd25Ob1NpemVLbm93bgUTS2V5S25vd25Ob1NpemVLbm93bgUKS2V5S25vd25ObwUKS2V5S25vd25Ob4CsqEC7E/h4r0QKF5BhzAO12Ew2', 95 | '__VIEWSTATEGENERATOR' => '3773DB32', 96 | '__EVENTVALIDATION' => '/wEWDQLIx7miDQL+rZa1DwLF9aauBQKCgfTXCQKFoeqeAwKeyrONDgKJgeHVCQLfjMXtCwK6oPefAwLM9cyPDALTnbbDBALIg+/HCgLnpLkgsEk/s5/S/hhQgiXIYo3SYzTjFR0=', 97 | 'EncryptedText' => urlencode(isset($_GET['raw'])?$_GET['a']:preg_replace('/\s+/', '',$_GET['a'])), 98 | 'Key' => '', 99 | 'KeyKnownRadioList' => 'KeyKnownNoSizeKnown', 100 | 'KeySizeKnown' => $i, 101 | 'ButtonCodebreak' => 'Codebreak!', 102 | 'KeyGuess' => '', 103 | 'Message' => '', 104 | 'authbox$usernameInput' => '', 105 | 'authbox$passwordInput' => '' 106 | );*/ 107 | $post = array( 108 | '__EVENTTARGET' => '', 109 | '__EVENTARGUMENT' => '', 110 | '__VIEWSTATE' => '/wEPDwULLTEwMDUxMTE5MDcPZBYCAgQPZBYIAgQPZBYEAgEPDxYEHgRUZXh0BRpOZXdlc3QgdXBkYXRlcyAoMy8zMS8yMDE3KR4LUG9zdEJhY2tVcmwFNGh0dHA6Ly93d3cubXlnZW9jYWNoaW5ncHJvZmlsZS5jb20vZGVmYXVsdC5hc3B4I25ld3NkZAIDDxYCHwAFigI8ZGl2IGlkPSJhdXRoZW50aWNhdGlvbkhlYWRlclRleHQiPjxhIGlkPSdzaWduSW5MaW5rJyBjbGFzcz0naGVhZGVyTGluaycgaHJlZj0naHR0cDovL3d3dy5teWdlb2NhY2hpbmdwcm9maWxlLmNvbS9sb2dpbnBhZ2UuYXNweCc+U0lHTiBJTjwvYT4gb3IgPGEgaWQ9J3NpZ25JbkxpbmsnIGNsYXNzPSdoZWFkZXJMaW5rJyBocmVmPSdodHRwOi8vd3d3Lm15Z2VvY2FjaGluZ3Byb2ZpbGUuY29tL2NyZWF0ZWxvZ2luLmFzcHgnPkNSRUFURSBBQ0NPVU5UPC9hPjwvZGl2PmQCCQ8QDxYCHgdDaGVja2VkaGRkZGQCDQ8QDxYCHwJnZGRkZAIRDxAPFgIfAmhkZGRkGAEFHl9fQ29udHJvbHNSZXF1aXJlUG9zdEJhY2tLZXlfXxYFBQtLZXlLbm93blllcwULS2V5S25vd25ZZXMFE0tleUtub3duTm9TaXplS25vd24FCktleUtub3duTm8FCktleUtub3duTm+Y7ibcAEO8E0qiR7H6fOIEDFo4Cg==', 111 | '__VIEWSTATEGENERATOR' => '3773DB32', 112 | '__EVENTVALIDATION' => '/wEWCwLg1MmlAgKArYCODwL+rZa1DwLF9aauBQKCgfTXCQKFoeqeAwKeyrONDgKJgeHVCQLfjMXtCwK6oPefAwLM9cyPDHQlFn7pfXiiusxXEhCVgSQmXrKI', 113 | 'EncryptedText' => urlencode(isset($_GET['raw'])?$_GET['a']:preg_replace('/\s+/', '',$_GET['a'])), 114 | 'Key' => '', 115 | 'KeyKnownRadioList' => 'KeyKnownNoSizeKnown', 116 | 'KeySizeKnown' => $i, 117 | 'ButtonCodebreak' => 'Codebreak!', 118 | 'KeyGuess' => '', 119 | 'Message' => '', 120 | 'authbox$usernameInput' => '', 121 | 'authbox$passwordInput' => '' 122 | ); 123 | array_push($data, array('url'=>'http://www.mygeocachingprofile.com/codebreaker.vigenerecipher.aspx','post'=>$post)); 124 | } 125 | 126 | $r = multiRequest($data); 127 | 128 | for($i = 0; $i < sizeof($r); $i++) { 129 | if(sizeof($r[$i])) { 130 | preg_match_all("~(?:MESSAGE w\/Key \#)(?:[\d]+)(?: = ')([^']*)(?:' ----------------)([^-]+)~", $r[$i], $matches); 131 | if($matches) { 132 | for($j = 0; $j < 3 && $j < sizeof($matches[0]); $j++) { 133 | echo '"'.$matches[1][$j].'|'.preg_replace('~[\r\n]+~', '', $matches[2][$j])."\"\n"; 134 | } 135 | } 136 | } 137 | } 138 | } 139 | 140 | } 141 | 142 | //POST /codebreaker.vigenerecipher.aspx HTTP/1.1 143 | //Host: www.mygeocachingprofile.com 144 | //User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0 145 | //Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 146 | //Accept-Language: nl,en-US;q=0.7,en;q=0.3 147 | //Accept-Encoding: gzip, deflate 148 | //Referer: http://www.mygeocachingprofile.com/codebreaker.vigenerecipher.aspx 149 | //Connection: keep-alive 150 | //Content-Type: application/x-www-form-urlencoded 151 | //Content-Length: 799 152 | // 153 | //__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwULLTE1OTUxODk4NzVkGAEFHl9fQ29udHJvbHNSZXF1aXJlUG9zdEJhY2tLZXlfXxYFBQtLZXlLbm93blllcwUTS2V5S25vd25Ob1NpemVLbm93bgUTS2V5S25vd25Ob1NpemVLbm93bgUKS2V5S25vd25ObwUKS2V5S25vd25Ob4CsqEC7E%2Fh4r0QKF5BhzAO12Ew2&__VIEWSTATEGENERATOR=3773DB32&__EVENTVALIDATION=%2FwEWDQLIx7miDQL%2BrZa1DwLF9aauBQKCgfTXCQKFoeqeAwKeyrONDgKJgeHVCQLfjMXtCwK6oPefAwLM9cyPDALTnbbDBALIg%2B%2FHCgLnpLkgsEk%2Fs5%2FS%2FhhQgiXIYo3SYzTjFR0%3D&EncryptedText=avzfzixexmjoirfpzkshdcalltcsuntdfmeufvjkhadpvvyedklwihvnrwfklwnxyckszilfzrfwxhulaimrjqlthbhqvrttrcpmowngzryewtwdvvvpkldbagpwvffnfljigtkwiengavzminlnhaycjqkjvyonzhysevglfrmodv&Key=&KeyKnownRadioList=KeyKnownNoSizeKnown&KeySizeKnown=10&ButtonCodebreak=Codebreak%21&KeyGuess=&Message=&authbox%24usernameInput=&authbox%24passwordInput= 154 | 155 | 156 | 157 | 158 | 159 | ?> 160 | 161 | -------------------------------------------------------------------------------- /UserSettings.js: -------------------------------------------------------------------------------- 1 | /* Users can edit their settings. */ 2 | 3 | //To disable specific algorithms, go to js/Global.js and change the corresponding boolean 4 | 5 | //Regex for matching files. For speed reasons start every signature with a ^ 6 | var REGEX_FILE_TYPES = /(^\x89PNG|^\xff\xd8\xff\xe0|^7z\xbc\xaf\x27\x1c|^PK\x03\x04|^GIF87a|^GIF89a|^%PDF)/i; //PNG, JPG, 7z, ZIP, GIF, GIF, PDF //https://en.wikipedia.org/wiki/List_of_file_signatures 7 | var REGEX_FLAG_DETECTION = /^(((ebctf|ctf|flag|t0k3n|token)(\(|\{)[^\)\}]{5,50}(\)|\}))|((\(|\{)[^\)\}]{5,50}(\)|\})(ftcbe|ftc|galf|n3k0t|nekot)))$/gi; // /^("ctf|flag|t0k3n)(\(|\{)[^\)\}]+(\)|\})$/i; 8 | 9 | //Passwords used in Vigenere, Playfair, columnar transposition, XOR(repeat), Bifid 10 | var brute_force_on_dictionary_keys = true; //value in [true|false] (boolean) //Default true //Disabling this will disable password guessing for decodings. It will speed up decription sometimes by a lot. 11 | var brute_force_dictionary_keys = [ 12 | 'password','secret','pass','test','code','key', //Maybe add: 'cargo','attackatonce','attackatdawn','Kryptos', 13 | //More words can be defined in PASSWORDS.js 14 | ]; 15 | 16 | //Trigger on special words (worth 5 points) which are longer than 4 characters. They are checked in order. Apparently needed to tripple escape. 17 | var output_analysis_dictionary = [ 18 | "ebctf","ctf\\\\{","ctf\\\\(","flag\\\\{","flag\\\\(","9447\\\\{","IW\\\\{","pCTF\\\\{","hacker","hackazon","hack","encoding","encoded","encode","decoding","decoded","decode","encrypted","encrypt","decrypted","decrypt", 19 | "cryptogram","crypto","crypt","graphy","cypher","decipher","cipher","convert","Kryptos","Krypto","CAFEBABE","BAADF00D","DEADBEAF","plaintext","congratulations","solution","solved","solving","hidden","command","prompt","i[pf]config","alphabet","english","translate","what is","coconut", 20 | "cyber","security","secure","secret","passw0rd","password","keyword","keyspace","submit","administrator","admin","random","backdoor","congrat","success","capture","internet","helloworld","unique","advance","significan(t|ce)","recogniz","setting","implementation","implement","digital","initialize","rebuild","anonymous","pirate","Windows","Linux", 21 | "shadow","forces","virtual","invisible","interpret","lucideee","digetaleee", //Morse from Kryptos sculpture 22 | "cyberlympics","lympics","Gam3z","Warl[o0]ck","WGZLiveLabs","WGZLive","LiveLab","t0k3n","t [o0] k [e3] n","y[o0]u s[e3]{2}k","s[e3]{2}k is","y[o0]us[e3]{2}k","\\\\.live\\\\.labs","FSociety", 23 | "tang0livelabs", "tang0\\\\.live\\\\.labs",'tang0','n1tr0n','megan','Targ3t','Mark83a', //CL2015 pre round 1 24 | 'GGoCySEA','GGoC','morpheus','DarkLord','illuminati','wgcode','(^|[^a-z0-9])wg[0-9a-z]{10}([^a-z0-9]|$)', //CL2016 pre round 1 25 | "affine","atbash","baconian","base64","binary","Caesar","Ceasar","Code39","barcode","enigma","Gronsfeld","Playfair","ROT13","substitution","Vigenere","Zigzag", //List of some crypto schemes (only 6 chars or longer) 26 | "C:\\\\\\\\","C:/","https?://","ftps?://","git://","bit\\\\.ly","dropbox","google","github","tinyurl","(([0-2][0-9]{2}|[0-9]{1,2})\\\\.){3}([0-2][0-9]{2}|[0-9]{1,2})(\\\\:[0-9]{2,5})?","\\\\.com","\\\\.net","\\\\.org","\\\\.nl/","\\\\.asp","\\\\.php","\\\\.png","\\\\.jpg","\\\\.apk","\\\\.exe","\\\\.bat","\\\\.vbs", 27 | "SHA-?(1|256|384|512)",//"MD5", 28 | //[ctf, flag, pair, ascii, token, hello, crack, error, switch] -> are moved to a low points category (3p or 1p) since their length is too short, coincidence factor is too large 29 | ]; 30 | 31 | 32 | // 33 | //All remaining settings can also be changed by the "Settings" button on the top-right. 34 | // 35 | 36 | var hide_workspace = false; //value in [true|false] (boolean) //Default false //To hide workspace HTML elements to speed up calculation of large inputs by preventing redraws 37 | var annoying_audio = true; //value in [true|false] (boolean) //Default true //You like Mario, right? 38 | var audio_path = 'media/Mario_Coin.mp3'; //value in String (path) //Default 'media/Mario_Coin.mp3' 39 | var sidebar_default_display = false; //value in [true|false] (boolean) //Default false //Hide sidebar with links to ciphers 40 | var explanation_default_display = true; //value in [true|false] (boolean) //Default true //Hide explanatory text 41 | 42 | //lookup_proxy_host can later be used to host our own quipqiup and playfair server to go fully offline 43 | var force_fully_offline = false; //value in [true|false] (boolean) //Default false //Never ever preform an online lookup. Can be used in case of client assignments. Overrides other online lookup settings. //Default false 44 | var auto_online_lookup = false; //value in [true|false] (boolean) //Default false //Auto execute quipqiup, playfair and vigenere after each change in text, it's overkill for easy crypto but maybe useful for hard ones 45 | var lookup_proxy_host = 'https://'; //value (URL starting with http(s)?:// ) (string) //Default 'https:///ServerSidePHP/' 46 | 47 | 48 | var min_encoded_string_length = 10; //value in [3..x] (integer) //Default 10 //When a too short value is entered it will decrease accuracy for short challenges 49 | var max_regular_string_length = 1024; //value in [1..x] (integer) //Default 1024 //If very long input is given, we can disable certain ciphers to speed up the process 50 | var auto_optimize_disable_ciphers = true; //value in [true|false] (boolean) //Default true //Disable certain ciphers when conditions are met. I.e. disable Viginere and Enigma when hex is detected since these ciphers work on strings. 51 | var enable_auto_decode = true; //value in [true|false] (boolean) //Default true //Disabling this will disable autoPwning encodings. It won't really help speed wise. 52 | var enable_auto_bruteforce = true; //value in [true|false] (boolean) //Default true //Disabling this will disable a great deal of the functionality, but also increase performance drastically 53 | var min_auto_guess_certainty = 2; //value in [0..5] (Enum-int, see Guess.js) //Default 2 = CertaintyEnum.WILDGUESS. 9001 = off //Decreasing this will result in whacky stuff, for instance when decrypting playfair/digraps 54 | var enable_reverse_output = true; //value in [true|false] (boolean) //Default true //Also try to grade the reverse output of every decryption. Disabling this won't really help speed wise but it will make output easier to read. 55 | var enable_workspace_cache = false; //value in [true|false] (boolean) //Default false //Will cache earlier calculated results. If WorkSpaces are broken/slow, please disable. 56 | var enable_strings_on_self = false; //value in [true|false] (boolean) //Default false //Will perform strings on itself. Bad for baconian. Good for CyberLympics?? 57 | 58 | var affine_B_bruteF_range = 0; //value in (integer): [0..25] (for letters only) or [0..94] (for hex) //Default 0 59 | var rotate_bruteF_range = 11; //value in [2..x] (integer) //Default 11 60 | var railfence_bruteF_range = 11; //value in [2..x] (integer) //Default 11 61 | var coltrans_bruteF_range = 11; //value in [2..x] (integer) //Default 11 62 | var coltrans_bruteF_permutations = 0; //value in [0..10ish] (integer) //Default 0 //Will blow up to x! (faculty)!! 63 | var coltrans_bruteF_lower_permutations = true; //value in [true|false] (boolean) //Default false 64 | var keyboardshift_bruteF_range = 10; //value in [1..x] (integer) //Default 10 65 | var skip_bruteF_range = 11; //value in [1..x] (integer) //Default 11 66 | -------------------------------------------------------------------------------- /css/base.css: -------------------------------------------------------------------------------- 1 | /********************************************* 2 | * let's use "base16-3024" as the default colour pallet. 3 | * https://terminal.sexy/#CQMApaKiCQMA2y0gAaJS_e0CAaDkoWqUteT0paKiXFhV2y0gAaJS_e0CAaDkoWqUteT09_f3 4 | *********************************************/ 5 | 6 | @font-face { 7 | font-family: Roboto; 8 | src: url('../media/Roboto-Regular.ttf'); 9 | } 10 | 11 | caption, table, thread, tbody, tr, td, th { 12 | font-size: inherit; 13 | font-family: inherit; 14 | font-weight: inherit; 15 | } 16 | 17 | th { 18 | font-weight: bold; 19 | } 20 | 21 | body { 22 | background-color: #FFFFFF; 23 | color: #000000; 24 | margin: 0px; 25 | overflow: auto; 26 | font-family: Roboto; 27 | } 28 | 29 | div.r_header { 30 | font-family: Roboto; 31 | font-size: 2.5em; 32 | font-style: italic; 33 | font-weight: bold; 34 | margin: 0; 35 | padding: 3px 8px 3px 8px; 36 | } 37 | 38 | div.r_headbar { 39 | font-weight: bold; 40 | display: table; 41 | width: 100%; 42 | padding: 8px 0px 4px 0px; 43 | border-bottom: 1px solid black; 44 | } 45 | 46 | div.r_headbarlinks { 47 | display: table-cell; 48 | float: left; 49 | font-family: Roboto; 50 | margin-left: 8px; 51 | } 52 | 53 | span.r_arr { 54 | font-family: courier; 55 | font-size: 0.75em; 56 | font-weight: normal; 57 | } 58 | 59 | div.r_headbarsearch { 60 | float: right; 61 | display: table-cell; 62 | margin-right: 8px; 63 | font-size: 0.8em; 64 | } 65 | 66 | input.r_headsearch { 67 | font-size: 0.8em; 68 | border: 1px solid black; 69 | } 70 | 71 | div.r_backlink { 72 | border: 3px #01A0E4 outset; 73 | padding: 0px 4px 0px 8px; 74 | margin: 0px; 75 | position:fixed; 76 | top: 39px; 77 | right: 3px; 78 | border-radius: 5px; 79 | } 80 | 81 | div.r_backlink a { 82 | text-decoration: none; 83 | } 84 | 85 | div.r_main, table.r_main { 86 | margin: 8px; 87 | padding: 3px; 88 | /*border: 1px solid black;*/ 89 | font-family: Roboto; 90 | background: white; 91 | } 92 | 93 | div.r_footbar { 94 | width: 100%; 95 | clear: both; 96 | border-top: 1px solid black; 97 | padding: 8px 0px 4px 0px; 98 | } 99 | 100 | iframe.r_chat { 101 | width: 100%; 102 | height: 100%; 103 | } 104 | 105 | td.r_info { 106 | font-size: 0.9em; 107 | padding-left: 16px; 108 | padding-right: 8px; 109 | } 110 | 111 | td.r_trivia { 112 | padding-left: 16px; 113 | padding-right: 8px; 114 | font-size: 0.8em; 115 | } 116 | 117 | sup { 118 | font-size: 65%; 119 | vertical-align: 0.8ex; 120 | } 121 | 122 | sub { 123 | font-size: 65%; 124 | vertical-align: -0.5ex; 125 | } 126 | 127 | a { color: #A16A94; } 128 | 129 | a:hover, a:active { color: #01A252; } 130 | 131 | a.r_link, td.r_info a, td.r_trivia a, a.r_menu2 { 132 | text-decoration: none; 133 | } 134 | 135 | body.r_chat { 136 | margin: 0px; 137 | padding: 0px; 138 | background: transparent; 139 | } 140 | 141 | body.r_chat span { 142 | font-size: 0.7em; 143 | } 144 | 145 | body.r_chat form { 146 | display: inline; 147 | margin: 0px; 148 | padding: 0px; 149 | } 150 | 151 | body.r_chat form input { 152 | border: 1px solid black; 153 | font-size: 0.7em; 154 | } 155 | 156 | table.r_box { 157 | border: 2px solid black; 158 | padding: 0px; 159 | } 160 | .ni1 { 161 | position: fixed; 162 | bottom: -3px; 163 | left: 50px; 164 | } 165 | .ni2 { 166 | position: fixed; 167 | top: 35px; 168 | left: 0px; 169 | } 170 | .ni3 { 171 | position: fixed; 172 | bottom: 90px; 173 | right: 0px; 174 | z-index: 2; 175 | } 176 | td.r_box { 177 | padding: 4px; 178 | margin: 0px; 179 | } 180 | 181 | p { 182 | margin-top: 4px; 183 | } 184 | 185 | h2{ 186 | color:#01A252; 187 | } 188 | 189 | h2.r_sect { 190 | margin-top: 0px; 191 | } 192 | 193 | ul.r_menu { 194 | padding: 0px; 195 | margin: 0px; 196 | float: left; 197 | list-style-type: none; 198 | } 199 | 200 | ul.r_menu > li { 201 | padding: 0px; 202 | margin: 0px; 203 | } 204 | 205 | ul.r_menu2 { 206 | list-style-type: none; 207 | background-color: white; 208 | margin: 0px; 209 | position: absolute; 210 | display: none; 211 | border: 2px solid black; 212 | color: black; 213 | padding: 0.4em; 214 | } 215 | 216 | ul.r_menu2 li:hover { 217 | background-color: #DFDFDF; 218 | } 219 | 220 | li:hover > ul.r_menu2 { 221 | display: block; 222 | } 223 | 224 | ul.r_menu2 > li { 225 | width: 100%; 226 | margin: 0px; 227 | display: block; 228 | } 229 | 230 | ul.r_menu2 > li > ul.r_menu2 { 231 | left: 8em; 232 | width: 100%; 233 | top: auto; 234 | } 235 | 236 | ul.r_menu2 > li > hr { 237 | margin: 10px 10% 6px 10%; 238 | border: 2px solid black; 239 | width: 80%; 240 | } 241 | 242 | div.adbox { 243 | margin-bottom: 5px; 244 | } 245 | -------------------------------------------------------------------------------- /css/jquery.orgchart.css: -------------------------------------------------------------------------------- 1 | 2 | #orgChartContainer { 3 | width: 100%; 4 | background-color: #B5E4F4; 5 | display: table; 6 | } 7 | #orgChart{ 8 | width: auto; 9 | height: auto; 10 | background-color: #B5E4F4; 11 | } 12 | 13 | div.orgChart { 14 | margin : 5px; 15 | padding : 35px 20px 20px 20px; 16 | } 17 | 18 | div.orgChart h2 { 19 | margin : 0px; 20 | font-size : 16px; 21 | font-weight: normal; 22 | min-height: 25px; 23 | } 24 | 25 | div.orgChart h2:hover { 26 | background: #fcfaca; 27 | cursor: text; 28 | } 29 | 30 | div.orgChart ul { 31 | list-style : none; 32 | margin : 4px; 33 | padding : 0px; 34 | font-size : 0.8em; 35 | text-align : left; 36 | } 37 | 38 | div.orgChart ul.stack, 39 | div.orgChart ul.stack ul { text-align : center; } 40 | 41 | div.orgChart table { width : 100%; } 42 | 43 | div.orgChart tr.lines td.line { 44 | width : 1px; 45 | height : 20px; 46 | } 47 | 48 | div.orgChart tr.lines td.top { border-top : 1px dashed black; } 49 | 50 | div.orgChart tr.lines td.left { border-right : 1px dashed black; } 51 | 52 | div.orgChart tr.lines td.right { border-left : 0px dashed black; } 53 | 54 | div.orgChart tr.lines td.half { width : 50%; } 55 | 56 | div.orgChart td { 57 | text-align : center; 58 | vertical-align : top; 59 | padding : 0px 2px; 60 | } 61 | 62 | div.orgChart div.node/*, div.orgChart div.node-guesses*/ { 63 | cursor : default; 64 | border : 1px solid #e7e7e7; 65 | display : inline-block; 66 | padding : 5px; 67 | width : 700px; 68 | /*height : 80px;*/ 69 | /*padding-bottom: 25px;*/ 70 | background: #ffffff; /* Old browsers */ 71 | background: -moz-linear-gradient(top, #ffffff 0%, #fbfbfb 100%); /* FF3.6+ */ 72 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #fbfbfb)); /* Chrome,Safari4+ */ 73 | background: -webkit-linear-gradient(top, #ffffff 0%, #fbfbfb 100%); /* Chrome10+,Safari5.1+ */ 74 | background: -o-linear-gradient(top, #ffffff 0%, #fbfbfb 100%); /* Opera 11.10+ */ 75 | background: -ms-linear-gradient(top, #ffffff 0%, #fbfbfb 100%); /* IE10+ */ 76 | background: linear-gradient(to bottom, #ffffff 0%, #fbfbfb 100%); /* W3C */ 77 | line-height : 1.3em; 78 | border-radius : 4px; 79 | -moz-border-radius : 4px; 80 | -webkit-border-radius : 4px; 81 | position: relative; 82 | box-shadow: 1px 1px 0px #ddd; 83 | } 84 | div.orgChart div.node-guesses { 85 | /*display: inline-block; 86 | padding: 2px;*/ 87 | font-size: 12px; 88 | } 89 | div.orgChart div.node h2{ 90 | display: inline; 91 | line-height: 20px; 92 | } 93 | 94 | table.equalwidth { 95 | table-layout: fixed; 96 | } 97 | table.equalwidth td { 98 | width: 11%; 99 | } 100 | 101 | .org-add-button, 102 | .org-length-indicator, 103 | .org-toggle-guessbar-button, 104 | .org-force-recalc-button, 105 | .org-del-button, 106 | .org-copy-button, 107 | .org-save-button, 108 | .org-confirm-del-button { 109 | /*position: absolute;*/ 110 | font-size: 12px; 111 | } 112 | 113 | 114 | 115 | .org-add-button { 116 | background: url(../media/add.png) no-repeat 0 3px; 117 | background-position: left 12px center; 118 | } 119 | 120 | .org-add-button:hover, 121 | .org-force-recalc-button:hover, 122 | .org-toggle-guessbar-button:hover, 123 | .org-copy-button:hover, 124 | .org-save-button:hover, 125 | .org-del-button:hover { 126 | background-color: #eef; 127 | border-radius: 2px; 128 | cursor: pointer; 129 | } 130 | .org-del-button { 131 | background: url(../media/delete.png) no-repeat; 132 | background-position: right 12px center; 133 | } 134 | 135 | .org-length-indicator{ 136 | /*bottom: 3px; 137 | left: 180px;*/ 138 | } 139 | 140 | .org-toggle-guessbar-button { 141 | /*background: url(../media/guess.jpg) no-repeat;*/ 142 | font-size: 17px; 143 | font-weight:bolder; 144 | color: #01A0E4; 145 | } 146 | .org-copy-button { 147 | background: url(../media/copy.png) no-repeat; 148 | } 149 | .org-save-button { 150 | background: url(../media/save.png) no-repeat; 151 | } 152 | 153 | .org-force-recalc-button { 154 | background: url(../media/refresh.png) no-repeat; 155 | } 156 | 157 | .org-length-indicator, 158 | .org-toggle-guessbar-button, 159 | .org-force-recalc-button, 160 | .org-copy-button, 161 | .org-save-button { 162 | background-position: center; 163 | } 164 | 165 | .certainty0, .certainty1, .certainty2, .certainty3, .certainty4, .certainty5 { 166 | background: white url(../media/guess.jpg) no-repeat 50% 4px; 167 | } 168 | .hitflag{ 169 | background: white url(../media/flag2.png) no-repeat 50% 5px; 170 | } 171 | 172 | 173 | .org-input { 174 | width: 665px; 175 | height: 80px; 176 | 177 | 178 | /*position:absolute; 179 | left:0; 180 | top:0; 181 | white-space:pre-wrap; 182 | word-wrap:break-word; 183 | /*resize:none;*/ 184 | } 185 | .org-desc { 186 | position: absolute; 187 | top: -27px; 188 | text-align: center; 189 | font-size: small; 190 | } 191 | 192 | .org-confirm-del-button { display: none; } 193 | -------------------------------------------------------------------------------- /js/ForceFlow.js: -------------------------------------------------------------------------------- 1 | 2 | var empty_init_node = [ 3 | {id: 1, name: '', parent: 0} 4 | ]; 5 | 6 | 7 | var ForceFlow = { 8 | //http://www.jqueryscript.net/chart-graph/Create-An-Editable-Organization-Chart-with-jQuery-orgChart-Plugin.html 9 | 10 | draw : function(keepoldvalue) { //Always execute ForceFlow.updateSelectedTextArea(); after a redraw $(function(){org_chart.draw();}); 11 | $(function(){org_chart.draw(keepoldvalue);}); 12 | ForceFlow.updateSelectedTextArea(); 13 | }, 14 | 15 | //Steps 16 | addStep : function(grade) { 17 | $(function(){org_chart.addNode({id: grade.random, name: grade.value, description: grade.cipher, parent: org_chart.getSelected()});}); 18 | }, 19 | addStepP : function(grade, parentid) { 20 | $(function(){org_chart.addNode({id: grade.random, name: grade.value, description: grade.cipher, parent: parentid?parentid:org_chart.getSelected()});}); 21 | }, 22 | addStepNoRedraw : function(grade) { 23 | $(function(){org_chart.addNodeNoRedraw({id: grade.random, name: grade.value, description: grade.cipher, parent: org_chart.getSelected()});}); 24 | }, 25 | addStepNoRedrawP : function(grade, parentid) { 26 | $(function(){org_chart.addNodeNoRedraw({id: grade.random, name: grade.value, description: grade.cipher, parent: parentid?parentid:org_chart.getSelected()});}); 27 | }, 28 | addStepAndGo : function(grade) { 29 | $(function(){ 30 | ForceFlow.addStep(grade); 31 | ForceFlow.setSelected(grade.random); 32 | ForceFlow.updateSelectedTextArea(); 33 | $(window).scroll();//.trigger("scroll") //Trigger scroll event for if a new childNode has appeared and selected 34 | }); 35 | }, 36 | addSteps : function(grades) { 37 | $(function(){ 38 | if(grades && $.isArray(grades)) { 39 | for(var i = 0; i < grades.length; i++){ 40 | ForceFlow.addStepNoRedrawP(grades[i], (i?grades[i-1].random:false)); 41 | } 42 | ForceFlow.draw(); 43 | } else if(grades) { 44 | alert('addSteps() reached single object no array condition, it\'s ok.'); 45 | ForceFlow.addStepNoRedraw(grades); 46 | ForceFlow.draw(); 47 | } 48 | }); 49 | }, 50 | addGuessStep : function(grade, certainty, guessType) { 51 | $(function(){org_chart.addNode({id: grade.random, name: grade.value, description: grade.cipher, style: "certainty"+certainty, guessType:guessType, parent: org_chart.getSelected()});}); 52 | }, 53 | addGuessStepNoRedraw : function(grade, certainty, guessType) { 54 | $(function(){org_chart.addNodeNoRedraw({id: grade.random, name: grade.value, description: grade.cipher, style: "certainty"+certainty, guessType:guessType, parent: org_chart.getSelected()});}); 55 | }, 56 | 57 | clear : function() { 58 | $(function(){org_chart.deleteNode(1);}); 59 | }, 60 | 61 | //Select 62 | setSelected : function(id) { 63 | $(function(){org_chart.setSelected(id);}); 64 | }, 65 | selectFurthestSingleChildNodePath : function() { 66 | $(function(){ForceFlow.setSelected(org_chart.getFurthestSingleChildNodePath());}); 67 | ForceFlow.updateSelectedTextArea(); 68 | $(window).scroll();//.trigger("scroll") //Trigger scroll event for if a new childNode has appeared and selected 69 | }, 70 | hasSelectedNodeChildren : function() { 71 | var ret = false; 72 | $(function(){ret = org_chart.hasSelectedNodeChildren();}); 73 | return ret; 74 | }, 75 | selectChild : function(parentid, childnr) { 76 | var ret = false; 77 | $(function(){ret = org_chart.selectChild(parentid, childnr);}); 78 | if(ret){ 79 | $(function(){ForceFlow.setSelected(ret);}); 80 | ForceFlow.updateSelectedTextArea(); 81 | $(window).scroll();//.trigger("scroll") //Trigger scroll event for if a new childNode has appeared and selected 82 | } 83 | return ret; 84 | }, 85 | getSelectedNodeNrChildren : function() { 86 | var ret = 0; 87 | $(function(){ret = org_chart.getSelectedNodeNrChildren();}); 88 | return ret; 89 | }, 90 | updateSelectedTextArea : function() { 91 | $(function(){CURRENTSCRATCHPAD = org_chart.getSelectedNodeTextArea();}); 92 | }, 93 | getNodeIdFromElement : function(element){ 94 | //return element.attr('node-id'); //DIMA:TestByDima 95 | for(var i = 0; i < element.attributes.length; i++){ 96 | if(element.attributes[i].name == 'node-id') 97 | return element.attributes[i].value; 98 | } 99 | return false; 100 | }, 101 | updateGuesses : function(guesses, id){ 102 | $(function(){org_chart.editNodeGuess(guesses, id);}); 103 | }, 104 | getCurrentNodeId : function(){ //TODO: Check if I can use another function for this. one that's faster. 105 | var id = 0; 106 | $(function(){id = org_chart.getSelected();}); 107 | return id; 108 | }, 109 | updateEditedNode : function(element){ 110 | $(function(){org_chart.updateEdited(ForceFlow.getNodeIdFromElement(element));}); 111 | }, 112 | /*setNodeValue : function(element, value){ 113 | $(function(){org_chart.setNodeValue(element, value);}); 114 | },*/ 115 | editNodeStyle : function(style){ 116 | $(function(){org_chart.editNodeStyle(style);}); 117 | } 118 | 119 | }; 120 | 121 | $(function(){ 122 | org_chart = $('#orgChart').orgChart({ 123 | data: empty_init_node, 124 | showControls: true, 125 | allowEdit: true, 126 | onAddNode: function(node){ 127 | log('Created new node on node '+node.data.id); 128 | org_chart.newNode(node.data.id); 129 | }, 130 | onDeleteNode: function(node){ 131 | log('Deleted node '+node.data.id); 132 | org_chart.deleteNode(node.data.id); 133 | ForceFlow.updateSelectedTextArea(); 134 | WorkSpaceManager.loadIfCached(); 135 | }, 136 | onClickNode: function(node){ 137 | log('Clicked node '+node.data.id); 138 | org_chart.setSelected(node.data.id); 139 | ForceFlow.updateSelectedTextArea(); 140 | WorkSpaceManager.loadIfCached(); 141 | }, 142 | onToggleGuessbar: function(node){ 143 | log('ToggleGuessbar '+node.data.id); 144 | org_chart.toggleGuessBarVisibility(node.data.id); 145 | }, 146 | }); 147 | }); 148 | 149 | if(! (window.navigator.userAgent.indexOf("MSIE ") > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) ) //Disable scroll effect for Internet Explorer 150 | { 151 | $(window).scroll(function(){ 152 | if(typeof org_chart !== "undefined") 153 | { 154 | //if (window.navigator.userAgent.indexOf("MSIE ") > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) 155 | // return; 156 | 157 | //var a = 200;//document.getElementById('top');//$('div[top=top]');//112; 158 | var pos = $(window).scrollTop(); 159 | var ptop = $( "div[id=top]" ); 160 | if(pos > Math.floor(ptop.offset().top)+50) { 161 | $('div[node-id='+org_chart.getSelected()+'] textarea').css({ 162 | position: 'fixed', 163 | top: (82+document.getElementById('orgChartContainer').style.paddingTop.slice(0,-2)*1)+'px', 164 | margin: '0 0 0 -335px', 165 | border: '3px #01A0E4 outset' 166 | }); 167 | } else { 168 | $('div[node-id='+org_chart.getSelected()+'] textarea').css({ 169 | position: 'initial', 170 | top: '0', 171 | margin: '0', 172 | border: '1px #A9A9A9 solid' 173 | }); 174 | } 175 | } 176 | }); 177 | } 178 | 179 | 180 | function log(text){ //Don't delete, it is still used. 181 | //$('#consoleOutput').append('

'+text+'

') 182 | } 183 | 184 | -------------------------------------------------------------------------------- /js/Global.js: -------------------------------------------------------------------------------- 1 | 2 | var InputTypeEnum = { 3 | UNKNOWN: -2, 4 | TOOSHORT: -1, 5 | UNINITIALIZED: 0, 6 | BINARY: 1, 7 | NUMBERS: 2, 8 | HEX: 3, 9 | IP: 4, 10 | ALPHA: 5, 11 | ALPHANUMERIC: 6, 12 | ALPHASPEC: 7, 13 | NUMERICSPEC: 8, 14 | ALPHANUMERICSPEC:9, 15 | NOTPRINTABLE: 10, 16 | FILE: 11, 17 | EXTENDEDASCII: 12, 18 | 19 | }; 20 | 21 | var Global = { 22 | Active : true, //Setting this to false will stop all calculations. 23 | 24 | InputType : InputTypeEnum.UNINITIALIZED, 25 | InputLength : -1, 26 | 27 | Switch_support : true, 28 | Switch_shuffle : true, 29 | Switch_substitute : true, 30 | Switch_decode : true, 31 | 32 | Enable : null, 33 | DefaultEnable : { 34 | Ascii_heatmap: true, 35 | Affine: true, 36 | Affine_BF: true, 37 | Affine_spec_BF: false, 38 | Atbash: true, 39 | Baconian: true, 40 | Baconian_BF: true, 41 | Base64: true, 42 | BaseX: true, 43 | BaudotMurray: true, 44 | Bifid: true, 45 | Bifid_BF: true, 46 | Caesar: true, 47 | Caesar_smart: false, 48 | Caesar_BF_XL: true, 49 | Code39: true, 50 | Colemak: true, 51 | ColumnTransp: true, 52 | ColumnTransp_BF:true, 53 | ColumnTransp_BF_PW:true, 54 | ColumnTransp_PERM:false, 55 | Digraph: true, 56 | Dvorak: true, 57 | Ebcdic: true, 58 | Enigma: true, 59 | Friedman_analysis:true, 60 | Goldenbug: true, 61 | Hex: true, 62 | Keyboardshift: true, 63 | L337Speak: true, 64 | LetterNumbers: true, 65 | LSB: true, 66 | Maze: true, 67 | Morse: true, 68 | Onetimepad: true, 69 | Playfair: true, 70 | Playfair_BF: true, 71 | Railfence: true, 72 | Railfence_BF: true, 73 | Rotate: true, 74 | Rotate_BF: true, 75 | RomanNumerals: true, 76 | Shift: true, 77 | Skip: true, 78 | Skip_BF: true, 79 | SpiritDVD: true, 80 | Substitute: true, 81 | Switch: true, 82 | Transposition: true, 83 | Vigenere: true, 84 | Vigenere_BF: true, 85 | WebApp: true, 86 | WeirdCrypto: false, //This functionality is also handled in AutoPWN 87 | XOR: true, 88 | XOR_Small: true, 89 | //XOR_Smart: true, 90 | XOR_BF_PW: true, 91 | XOR_BF_XL: true, 92 | 93 | Dev: false, 94 | }, 95 | log : function(text) 96 | { 97 | console.info("Step "+Timer.iteration+" - "+text); 98 | }, 99 | warn : function(text) 100 | { 101 | console.warn("Step "+Timer.iteration+" - "+text); 102 | }, 103 | printEnabled : function() 104 | { 105 | var loglineEnabled = "enabled: \r\n"; 106 | var loglineDisabled = "disabled: \r\n"; 107 | for (var key in this.Enable) { 108 | if(this.Enable[key]) 109 | loglineEnabled += key+', '; 110 | else 111 | loglineDisabled += key+', '; 112 | } 113 | this.log(loglineEnabled); 114 | this.log(loglineDisabled); 115 | }, 116 | printEnabledSettings : function() 117 | { 118 | var allHTML = ['','','','','','','']; //more than enough potential rows 119 | var i = 0; 120 | var groupMaxSize = 20; 121 | for (var key in this.Enable) { 122 | allHTML[Math.floor(i/groupMaxSize)] += SettingsManager.newToggleHTML(new Setting('Global.DefaultEnable.'+key,'bool',key,'')); 123 | i++; 124 | } 125 | return allHTML; 126 | }, 127 | printEnabledSettingsHTML : function() 128 | { 129 | var allHTML = ''; 130 | var settingsrow = Global.printEnabledSettings(); 131 | for (var i = 0; i < settingsrow.length && settingsrow[i].length; i++) { 132 | allHTML += ''+settingsrow[i]+'
'; 133 | } 134 | allHTML += ''; 135 | return allHTML; 136 | }, 137 | 138 | toggleAutoDecode : function (element) { 139 | $(element).toggleClass("manualGuessButton"); 140 | var text = $(element).text(); 141 | $(element).text(text == "Decode on" ? "Decode off" : "Decode on"); 142 | enable_auto_decode = !enable_auto_decode; 143 | }, 144 | toggleAutoBruteForce : function (element) { 145 | $(element).toggleClass("manualGuessButton"); 146 | var text = $(element).text(); 147 | $(element).text(text == "BruteForce on" ? "BruteForce off" : "BruteForce on"); 148 | enable_auto_bruteforce = !enable_auto_bruteforce; 149 | }, 150 | setAutoGuessSensitivity : function (element) { 151 | min_auto_guess_certainty=element.value; 152 | element.className=element.value>9000?'blueSelectDropdown manualSelectDropdown':'blueSelectDropdown'; 153 | }, 154 | 155 | hideWorkSpaceVisibility : function (hide) { 156 | if(hide) 157 | $('#WORKSPACE').hide(); 158 | else 159 | $('#WORKSPACE').show(); 160 | }, 161 | 162 | resetEnableToDefault : function () 163 | { 164 | this.Enable = $.extend({}, this.DefaultEnable); 165 | }, 166 | 167 | start : function () 168 | { 169 | this.Active = true; 170 | this.log('Started computation.'); 171 | }, 172 | stop : function () 173 | { 174 | this.Active = false; 175 | this.log('Stopped and aborted computation.'); 176 | }, 177 | }; 178 | 179 | 180 | Global.resetEnableToDefault(); 181 | 182 | if(lookup_proxy_host.length<10)lookup_proxy_host=window.atob('aHR0cHM6Ly9zY3dmLmRpbWEubmluamEvU2VydmVyU2lkZVBIUC8='); //Well, at least default to something 183 | 184 | $(document).ready(function(){ 185 | $('a#ENABLE_AUTO_DECODE').click(function(){Global.toggleAutoDecode(this)}); 186 | 187 | $('a#ENABLE_AUTO_BRUTEFORCE').click(function(){Global.toggleAutoBruteForce(this)}); 188 | }); 189 | 190 | 191 | 192 | /*(function() { 193 | var exLog = console.info; 194 | console.ninfo = function(msg) { 195 | exLog.apply(this, arguments); 196 | alert(msg); 197 | } 198 | })();*/ 199 | 200 | -------------------------------------------------------------------------------- /js/Grade.js: -------------------------------------------------------------------------------- 1 | //http://book.mixu.net/node/ch6.html 2 | //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript 3 | //Avoid assigning variables to prototypes but use gradeobj.random=value or gradeobj['random']=value 4 | 5 | // Constructor 6 | function Grade(id, r, grade, value, markedvalue, cipher) { 7 | // always initialize all instance properties 8 | this.id = id; 9 | this.random = r; 10 | this.grade = grade; 11 | this.value = value; 12 | this.markedvalue = markedvalue; 13 | this.cipher = cipher; 14 | this.intermediateSteps = []; 15 | } 16 | // class methods 17 | Grade.prototype.getInfoArray = function() { 18 | return [this.id, this.random, this.grade, this.value, this.markedvalue, this.cipher]; 19 | }; 20 | // export the class 21 | //module.exports = Grade; 22 | 23 | 24 | // constructor call 25 | //var object = new Grade(r, grade, value, markedvalue, cipher); 26 | -------------------------------------------------------------------------------- /js/Moar.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /js/OLD_code.js: -------------------------------------------------------------------------------- 1 | var alphabet = '0123456789abcdefghjkmnpqrtuvwxyz'; 2 | var alias = { o:0, i:1, l:1, s:5 }; 3 | var table = {}; 4 | var lookup = function() { 5 | table = {}; 6 | // Invert 'alphabet' 7 | for (var i = 0; i < alphabet.length; i++) { 8 | table[alphabet[i]] = i; 9 | } 10 | // Splice in 'alias' 11 | for (var key in alias) { 12 | if (!alias.hasOwnProperty(key)) 13 | continue; 14 | table[key] = table['' + alias[key]]; 15 | } 16 | lookup = function() { return table; } 17 | return table; 18 | } 19 | function toCrockfordBase32(input) 20 | { 21 | var skip = 0; // how many bits we have from the previous character 22 | var curbyte = 0; // current byte we're producing 23 | var output = ''; 24 | for (var i = 0; i < input.length; i++) { 25 | curchar = input[i]; 26 | if (typeof curchar != 'string'){ 27 | if (typeof curchar == 'number') { 28 | curchar = String.fromCharCode(curchar); 29 | } 30 | } 31 | //input[i] = input[i].toLowerCase(); 32 | var val = lookup()[curchar.toLowerCase()]; 33 | if (typeof val == 'undefined') { 34 | // character does not exist in our lookup table 35 | alert('Lookup failed @'+i+' '+curchar.toLowerCase()); 36 | return false; // skip silently. An alternative would be: 37 | // throw Error('Could not find character "' + input[i] + '" in lookup table.') 38 | } 39 | val <<= 3; // move to the high bits 40 | curbyte |= val >>> skip; 41 | skip += 5; 42 | if (skip >= 8) { 43 | // we have enough to preduce output 44 | output += String.fromCharCode(curbyte); 45 | skip -= 8; 46 | if (skip > 0) 47 | curbyte = (val << (5 - skip)) & 255; 48 | else 49 | curbyte = 0; 50 | //alert(output); 51 | } 52 | } 53 | //var output = this.output; 54 | //this.output = ''; 55 | alert(output); 56 | if (true /*flush*/) { 57 | output += (skip < 0 ? alphabet[bits >> 3] : '') + (false ? '$' : ''); 58 | } 59 | alert(output); 60 | return output; 61 | } -------------------------------------------------------------------------------- /js/Student.js: -------------------------------------------------------------------------------- 1 | /* 2 | Add checks for hashes in answers 3 | Add standardized functions for checking if something is a base64, binary, plaintext, plaintext++ 4 | */ 5 | 6 | 7 | //AKA Guesser 8 | var Student = { 9 | active : false, 10 | current_test_case_str : '', 11 | runNextTestCase_timeout : 300, 12 | initialcheck_timeout : 550, 13 | check_onlinelookup_timeout : 8000, 14 | check_onlineplayfair_timeout : 2000, 15 | //check_final_try_timeout : 2000, 16 | onlineplayfair_performed : true, 17 | onlinelookup_performed : true, 18 | one_extra_extention : true, 19 | //final_extention : true, 20 | 21 | MYTESTANSWERS : [], 22 | 23 | startGuessAll : function() { 24 | if(this.active == false) { 25 | var parentid = ForceFlow.getCurrentNodeId(); 26 | var nrChildren = ForceFlow.getSelectedNodeNrChildren(); 27 | if(nrChildren >= 1) { 28 | this.active = true; 29 | this.MYTESTANSWERS = []; 30 | this.nextGuess(parentid); 31 | } 32 | } else{ 33 | console.info("Student is already guessing @ startGuessAll()"); 34 | } 35 | }, 36 | nextGuess : function(parentid, childnr) 37 | { 38 | childnr = (typeof childnr !== 'undefined')?childnr+1:0; 39 | if(childnr < 20 && ForceFlow.selectChild(parentid, childnr)) //20 is an insane high number here 40 | { 41 | this.one_extra_extention = false; 42 | this.onlineplayfair_performed = false; 43 | window.setTimeout('\tStudent.followGuess('+parentid+','+childnr+')', this.runNextTestCase_timeout); 44 | } 45 | else 46 | { 47 | //We're out of guesses, stop 48 | this.stopGuessing(); 49 | } 50 | }, 51 | /*clearAllAnswers:function(){},clearAllGrades:function(){},*/showCalculating:function(){}, 52 | followGuess : function(parentid, childnr) 53 | { 54 | var highestGrade = Teacher.getHighestGrade(false); 55 | if(Teacher.isHit(highestGrade)) 56 | { 57 | this.MYTESTANSWERS[this.MYTESTANSWERS.length] = highestGrade; 58 | console.info("\tPauzed guessing because of hit :)"); 59 | this.stopGuessing(); 60 | return; 61 | } 62 | 63 | if(CURRENTSCRATCHPAD.realvalue == this.current_test_case_str) 64 | { 65 | //this.current_test_case_str = CURRENTSCRATCHPAD.realvalue; 66 | if(this.one_extra_extention == false) //Give it a bit more time before we continue with the next guess 67 | { 68 | this.one_extra_extention = true; 69 | window.setTimeout('Student.followGuess('+parentid+','+childnr+')', this.initialcheck_timeout); 70 | } 71 | else if(this.onlineplayfair_performed == false && OnlineLookup.active != 0) 72 | { 73 | this.onlineplayfair_performed = true; 74 | window.setTimeout('Student.followGuess('+parentid+','+childnr+')', this.check_onlineplayfair_timeout); 75 | } 76 | else if(this.onlinelookup_performed == false) 77 | { 78 | this.onlinelookup_performed = true; 79 | window.setTimeout('Student.followGuess('+parentid+','+childnr+')', this.check_onlinelookup_timeout - this.check_onlineplayfair_timeout); 80 | alert('A'); 81 | } 82 | else 83 | { 84 | window.setTimeout('Student.nextGuess('+parentid+','+childnr+')', this.runNextTestCase_timeout); 85 | } 86 | } 87 | else 88 | { 89 | this.one_extra_extention = false; 90 | this.current_test_case_str = CURRENTSCRATCHPAD.realvalue; 91 | window.setTimeout('Student.followGuess('+parentid+','+childnr+')', this.initialcheck_timeout); 92 | } 93 | 94 | }, 95 | stopGuessing : function() 96 | { 97 | //Done guessing 98 | //if(this.MYTESTANSWERS.length) 99 | 100 | this.active = false; 101 | }, 102 | 103 | 104 | }; -------------------------------------------------------------------------------- /js/Test.js: -------------------------------------------------------------------------------- 1 | 2 | var Test = { 3 | runNextTestCase_timeout : 50, 4 | initialcheck_timeout : UPDATE_SETTIMEOUT+50, 5 | check_onlinelookup_timeout : 8000, 6 | check_final_try_timeout : 2000, 7 | 8 | current_test_case : -1, 9 | current_test_case_str : '', 10 | onlinelookup_performed : false, 11 | one_extra_extention : false, 12 | final_extention : false, 13 | 14 | MYTESTANSWERS : [], 15 | 16 | CURRENTCHALLANGESET : false, 17 | 18 | active : function() 19 | { 20 | return (this.current_test_case >= 0); //current_test_case == -1 means inactive 21 | }, 22 | 23 | initTestMode : function(challangeset) 24 | { 25 | if(UPDATE_SETTIMEOUT == 0) 26 | alert('MAIN.js should be included before TEST.js'); 27 | 28 | this.CURRENTCHALLANGESET = (typeof challangeset == "undefined")? TESTCHALLANGES/*.slice(0)*/ : ALLTESTCHALLANGES/*.slice(0)*/; 29 | 30 | //this.CURRENTCHALLANGESET = this.CURRENTCHALLANGESET.reverse(); 31 | 32 | this.current_test_case = 0; 33 | this.MYTESTANSWERS = []; 34 | Test.runNextTestCase(); 35 | Timer.startN('AllTests'); 36 | return false; 37 | }, 38 | 39 | runNextTestCase : function() { 40 | this.onlinelookup_performed = false; 41 | this.one_extra_extention = false; 42 | this.final_extention = false; 43 | 44 | if(this.current_test_case < this.CURRENTCHALLANGESET.length) { 45 | //ForceFlow.clear(); 46 | //ForceFlow.updateSelectedTextArea(); 47 | //confirm('Next'); 48 | Teacher.clearAllGrades(); 49 | this.current_test_case_str = this.CURRENTCHALLANGESET[this.current_test_case][0]; 50 | CURRENTSCRATCHPAD.setRealValue(this.CURRENTCHALLANGESET[this.current_test_case][0]); 51 | ForceFlow.updateEditedNode(CURRENTSCRATCHPAD); // or something like $(CURRENTSCRATCHPAD).change(); (but this function isn't implemented yet) 52 | window.setTimeout('Test.checkTestCase()', this.initialcheck_timeout); 53 | } else { 54 | var duration = Test.stop(); 55 | alert("All tests cleared! - "+duration+"ms"); 56 | } 57 | }, 58 | 59 | checkTestCase : function() 60 | { 61 | var highestGrade = Teacher.getHighestGrade(false); 62 | if(Teacher.isHit(highestGrade)) 63 | { 64 | this.MYTESTANSWERS[this.MYTESTANSWERS.length] = highestGrade[2]; 65 | if(highestGrade[2] != this.CURRENTCHALLANGESET[this.current_test_case][1]) { 66 | if(! confirm("Calc:"+highestGrade[2]+ "\r\nAnsw:"+this.CURRENTCHALLANGESET[this.current_test_case][1] + "\r\nContinue testing?") ) 67 | { 68 | Test.stop(); 69 | return; 70 | } 71 | } 72 | 73 | this.current_test_case += 1; 74 | Test.runNextTestCase(); 75 | //window.setTimeout('Test.runNextTestCase();', this.runNextTestCase_timeout); 76 | } 77 | else if(CURRENTSCRATCHPAD.realvalue != this.current_test_case_str) 78 | { 79 | this.current_test_case_str = CURRENTSCRATCHPAD.realvalue; 80 | window.setTimeout('Test.checkTestCase()', this.initialcheck_timeout); 81 | } 82 | else if(this.one_extra_extention == false) //Give it a bit more time before we do quipqiup 83 | { 84 | this.one_extra_extention = true; 85 | window.setTimeout('Test.checkTestCase()', this.initialcheck_timeout); 86 | } 87 | else if(this.onlinelookup_performed == false) //Try quipqiup and playfair online lookup 88 | { 89 | this.onlinelookup_performed = true; 90 | if(!OnlineLookup.active) 91 | OnlineLookup.request(CURRENTSCRATCHPAD.realvalue); 92 | window.setTimeout('Test.checkTestCase()', this.check_onlinelookup_timeout); 93 | } 94 | else if(this.final_extention == false) //Final check, in case quipqiup response is in a traffic jam 95 | { 96 | this.final_extention = true; 97 | window.setTimeout('Test.checkTestCase()', this.check_final_try_timeout); 98 | } 99 | else 100 | { 101 | if(confirm('Test failed (timeout) at @ test #'+(this.current_test_case+1)+" of "+this.CURRENTCHALLANGESET.length+'. Continue testing?')) { 102 | this.current_test_case += 1; 103 | Test.runNextTestCase(); 104 | } 105 | else 106 | { 107 | Test.stop(); 108 | } 109 | } 110 | }, 111 | 112 | stop : function() 113 | { 114 | this.current_test_case = -1; 115 | ForceFlow.clear(); 116 | ForceFlow.updateSelectedTextArea(); 117 | $("span.outputbox").empty(); //Same as Teacher.clearAllAnswers() 118 | return Timer.stopN('AllTests',"AllTests - all"); 119 | } 120 | 121 | }; 122 | -------------------------------------------------------------------------------- /js/TestCasesAll.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/js/TestCasesAll.js -------------------------------------------------------------------------------- /js/WorkSpace.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | // Constructor 4 | function WorkSpace(realvalue, htmlobjects, allgrades) { 5 | // always initialize all instance properties 6 | this.realvalue = realvalue; 7 | this.htmlobjects = htmlobjects; 8 | //this.html = html; 9 | this.allgrades = allgrades; 10 | } 11 | // class methods 12 | WorkSpace.prototype.get = function() { 13 | return [this.realvalue, this.htmlobjects, this.allgrades]; 14 | }; 15 | 16 | var WorkSpaceManager = { 17 | 18 | workSpaces : [], 19 | currentWorkSpaceRealValue : '', 20 | 21 | save : function() 22 | { 23 | if(enable_workspace_cache && ! Test.active()){ //Do not enable caching during testing 24 | //Save workspace in struct using jQuery 25 | if(!WorkSpaceManager.findWorkSpace(CURRENTSCRATCHPAD.realvalue)) { 26 | Timer.start(); 27 | this.workSpaces.push(WorkSpaceManager.getCurrentWorkspace()); 28 | Timer.stop( 'WorkSpaceManager - saved WorkSpace to cache. '/*+CURRENTSCRATCHPAD.realvalue*/); 29 | } 30 | this.currentWorkSpaceRealValue = CURRENTSCRATCHPAD.realvalue; 31 | } 32 | }, 33 | getCurrentWorkspace : function() 34 | { 35 | var htmlobjects = $('#WORKSPACE').children().clone(true, true); 36 | return new WorkSpace(CURRENTSCRATCHPAD.realvalue, htmlobjects, Teacher.getAllGrades()); 37 | }, 38 | findWorkSpace : function(realvalue) 39 | { 40 | for (var i = this.workSpaces.length - 1; i >= 0; i--) { 41 | if(this.workSpaces[i].realvalue == CURRENTSCRATCHPAD.realvalue) { 42 | return this.workSpaces[i]; 43 | } 44 | } 45 | return false; 46 | }, 47 | loadIfCached : function() 48 | { 49 | if(enable_workspace_cache && CURRENTSCRATCHPAD.realvalue != this.currentWorkSpaceRealValue && ! Test.active()) { //If there is something that needs to be done AND not during testing 50 | var ws = WorkSpaceManager.findWorkSpace(CURRENTSCRATCHPAD.realvalue); 51 | if(ws) { 52 | Timer.start(); 53 | WorkSpaceManager.loadThisWorkspace(ws); 54 | Timer.stop( 'WorkSpaceManager - loaded WorkSpace from cache.'/*+ws.realvalue */); 55 | return true; 56 | } 57 | } 58 | return false; 59 | }, 60 | loadThisWorkspace : function(ws) 61 | { 62 | $('#WORKSPACE').empty().append(ws.htmlobjects.clone(true, true)); //Load workspace using jQuery 63 | //IsUnchangedVar = ws.IsUnchangedVar; 64 | //IsUnchangedVar.text = 1; 65 | Teacher.setAllGrades(ws.allgrades); 66 | IsUnchanged(CURRENTSCRATCHPAD); 67 | this.currentWorkSpaceRealValue = CURRENTSCRATCHPAD.realvalue; 68 | //console.log('\tWorkSpaceManager loaded WorkSpace from cache.'+ws.realvalue); 69 | }, 70 | showCurrentCache : function() 71 | { 72 | for (var i = this.workSpaces.length - 1, ws; i >= 0; i--) { 73 | var win = window.open('', '', ''); 74 | if(win) win.document.write(''+this.workSpaces[i].htmlobjects[0].outerHTML+'




'+this.workSpaces[i].realvalue+'
'); 75 | } 76 | }, 77 | clear : function() 78 | { 79 | this.workSpaces = []; 80 | }, 81 | }; -------------------------------------------------------------------------------- /js/cipher/affine.js: -------------------------------------------------------------------------------- 1 | // Affine Cipher 2 | 3 | // This code was written by Tyler Akins and is placed in the public domain. 4 | // It would be nice if this header remained intact. http://rumkin.com 5 | 6 | // Requires util.js 7 | 8 | var Affine = { 9 | coprimesof26 : [3,5,7,9,11,15,17,19,21,23,25], 10 | coprimesof95 : [2,3,4,6,7,8,9,11,12,13,14,16,17,18,21,22,23,24,26,27,28,29,31,32,33,34,36,37,39,41,42,43,44,46,47,48,49,51,52,53,54,56,58,59,61,62,63,64,66,67,68,69,71,72,73,74,77,78,79,81,82,83,84,86,87,88,89,91,92,93,94], 11 | 12 | upd : function() 13 | { 14 | if (IsUnchangedVar.a * IsUnchangedVar.b * 15 | IsUnchangedVar.encdec * IsUnchangedVar.text) 16 | { 17 | //window.setTimeout('AFFINE_upd()', 100); 18 | return; 19 | } 20 | 21 | var e = document.getElementById('AFFINE_output'); 22 | 23 | if (CURRENTSCRATCHPAD.realvalue == '') 24 | { 25 | e.innerHTML = 'Type in a message and see the results here!'; 26 | } 27 | else 28 | { 29 | Timer.start(); 30 | 31 | var encdec = document.encoder.encdec.value * 1; 32 | var value = CURRENTSCRATCHPAD.realvalue; 33 | 34 | e.innerHTML = Affine.calc(encdec, 35 | value, 36 | document.encoder.a.value * 1, document.encoder.b.value * 1); 37 | Teacher.analyzeField("AFFINE_output", 'affine()'); 38 | 39 | Timer.stop("Affine - Single"); 40 | 41 | Timer.start(); 42 | var b = document.encoder.b.value*1; 43 | var o = document.getElementById('AFFINE_output_bruteF'); 44 | var out = ''; 45 | 46 | var b_from = b, b_to = b; 47 | if(affine_B_bruteF_range) { 48 | var b_from = 0; 49 | var b_to = Math.min(affine_B_bruteF_range,25); 50 | } 51 | for(var j = b_from; j <= b_to; j++) 52 | { 53 | out += '

B:'+j+'

'; 54 | for(var i = 0; i < this.coprimesof26.length; i++) { 55 | //while (! IsCoprime(i, 26)) i ++; 56 | var r = Affine.calc(encdec, 57 | value, 58 | this.coprimesof26[i], 59 | j); 60 | r = encdec < 0?Teacher.analyzeValue(r, 'affine'+this.coprimesof26[i]+'()'):r; 61 | out += 'Affine '+this.coprimesof26[i]+': '+r+"
\n"; 62 | } 63 | } 64 | o.innerHTML = out; 65 | Timer.stop("Affine - BruteF over "+this.coprimesof26.length+'x'+((b_to-b_from)+1)+' = '+this.coprimesof26.length*((b_to-b_from)+1)); 66 | 67 | if(Global.Enable.Affine_spec_BF) 68 | { 69 | Timer.start(); 70 | //51x34-> :!TwBTwB8B/i6MBwF6KF6?FB&!T?!BTwBF6?T=!FDFrB&TK!B8yyT6FsB:!FB!8w!ByiDBK!FB6FYKB?T=FDBTwB\FF"r\)rNN7r)FNjFNyF8cUc8NzUy87?B@B.8[F 71 | var alphabet = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; //Note the space in the front! 72 | var o2 = document.getElementById('AFFINE_output_spec_bruteF'); 73 | var out2 = ''; 74 | 75 | if(affine_B_bruteF_range) { 76 | var b_from = 0; 77 | var b_to = Math.min(affine_B_bruteF_range,94); 78 | } 79 | for(var j = b_from; j <= b_to; j++) 80 | { 81 | out2 += '

B:'+j+'

'; 82 | for(var i = 0; i < this.coprimesof95.length; i++) { 83 | //while (! IsCoprime(i, 95)) i ++; 84 | var r = Affine.calc(encdec, 85 | value, 86 | this.coprimesof95[i], 87 | j, 88 | null, alphabet); 89 | r = encdec < 0?Teacher.analyzeValue(r, 'affine_spec_'+this.coprimesof95[i]+'()'):r; 90 | out2 += 'Affine(0x20-0x7E):'+this.coprimesof95[i]+': '+r+"
\n"; 91 | } 92 | } 93 | o2.innerHTML = out2; 94 | Timer.stop("Affine - BruteF spec over "+this.coprimesof95.length+'x'+((b_to-b_from)+1)+' = '+this.coprimesof95.length*((b_to-b_from)+1)); 95 | } 96 | } 97 | 98 | //window.setTimeout('AFFINE_upd()', 100); 99 | }, 100 | 101 | a_plus : function () 102 | { 103 | var a = document.encoder.a.value; 104 | if (a < 1) 105 | { 106 | a = 1; 107 | } 108 | else 109 | { 110 | a ++; 111 | while (! IsCoprime(a, 26)) 112 | { 113 | a ++; 114 | } 115 | } 116 | document.encoder.a.value = a; 117 | }, 118 | 119 | a_minus : function() 120 | { 121 | var a = document.encoder.a.value; 122 | if (a < 2) 123 | { 124 | a = 1; 125 | } 126 | else 127 | { 128 | a --; 129 | while (! IsCoprime(a, 26)) 130 | { 131 | a --; 132 | } 133 | } 134 | document.encoder.a.value = a; 135 | }, 136 | b_plus : function () 137 | { 138 | var b = document.encoder.b.value; 139 | if (b < 0) { 140 | b = 0; 141 | } else { 142 | b++; 143 | if (b > 94) { 144 | b = 94; 145 | } 146 | } 147 | document.encoder.b.value = b; 148 | }, 149 | 150 | b_minus : function() 151 | { 152 | var b = document.encoder.b.value; 153 | if (b < 1) { 154 | b = 0; 155 | } else { 156 | b--; 157 | } 158 | document.encoder.b.value = b; 159 | }, 160 | 161 | 162 | encode: function(text, mult, inc, key, alphabet) 163 | { 164 | return Affine.calc(1, text, mult, inc, key, alphabet); 165 | }, 166 | decode: function(text, mult, inc, key, alphabet) 167 | { 168 | return Affine.calc(-1, text, mult, inc, key, alphabet); 169 | }, 170 | 171 | // Perform a Affine transformation on the text 172 | // encdec = -1 for decode, 1 for encode (kinda silly, but kept it like this 173 | // to be the same as the other encoders) 174 | // text = the text to encode/decode 175 | // inc = how far to shift the letters. 176 | // key = the key to alter the alphabet 177 | // alphabet = The alphabet to use if not A-Z 178 | calc: function(encdec, text, mult, inc, key, alphabet) 179 | { 180 | var s = ""; 181 | 182 | if (typeof(alphabet) != 'string') 183 | alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 184 | 185 | mult = mult * 1; 186 | inc = inc * 1; 187 | 188 | if (encdec < 0) { 189 | var i = 1; 190 | while ((mult * i) % alphabet.length != 1) { 191 | i += 2; 192 | } 193 | mult = i; 194 | inc = mult * (alphabet.length - inc) % alphabet.length; 195 | } 196 | 197 | key = MakeKeyedAlphabet(key, alphabet); 198 | 199 | for (var i = 0; i < text.length; i++) 200 | { 201 | var b = text.charAt(i); 202 | var idx; 203 | if ((idx = alphabet.indexOf(b)) >= 0) 204 | { 205 | idx = (mult * idx + inc) % alphabet.length; 206 | b = key.charAt(idx); 207 | } 208 | else if ((idx = alphabet.indexOf(b.toUpperCase())) >= 0) 209 | { 210 | idx = (mult * idx + inc) % alphabet.length; 211 | b = key.charAt(idx).toLowerCase(); 212 | } 213 | s += b; 214 | } 215 | return s; 216 | } 217 | }; 218 | 219 | -------------------------------------------------------------------------------- /js/cipher/atbash.js: -------------------------------------------------------------------------------- 1 | 2 | var Atbash = { 3 | 4 | upd : function() 5 | { 6 | if (IsUnchangedVar.text) 7 | { 8 | //window.setTimeout('ATBASH_upd()', 100); 9 | return; 10 | } 11 | 12 | var e = document.getElementById('ATBASH_output'); 13 | 14 | if (CURRENTSCRATCHPAD.realvalue == '') 15 | { 16 | e.innerHTML = 'Type in a message and see the results here!'; 17 | } 18 | else 19 | { 20 | Timer.start(); 21 | e.innerHTML = /*SwapSpaces(HTMLEscape(*/Affine.calc(1, CURRENTSCRATCHPAD.realvalue, 25, 25); 22 | Teacher.analyzeField("ATBASH_output", 'atbash()'); 23 | Timer.stop("Atbash - Single"); 24 | } 25 | 26 | //window.setTimeout('ATBASH_upd()', 100); 27 | } 28 | 29 | }; 30 | -------------------------------------------------------------------------------- /js/cipher/baconian.js: -------------------------------------------------------------------------------- 1 | var Baconian = { 2 | 3 | upd : function() 4 | { 5 | if (IsUnchangedVar.text * 6 | IsUnchangedVar.rem_jv * 7 | IsUnchangedVar.encdec) 8 | { 9 | //window.setTimeout('BACONIAN_upd()', 100); 10 | return; 11 | } 12 | 13 | //ResizeTextArea(CURRENTSCRATCHPAD); 14 | 15 | var e = document.getElementById('BACONIAN_output'); 16 | var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 17 | var txt = CURRENTSCRATCHPAD.realvalue; 18 | 19 | if (CURRENTSCRATCHPAD.realvalue == '') 20 | { 21 | e.innerHTML = 'Type in a message and see the results here!'; 22 | } 23 | else if (document.encoder.encdec.value * 1 == 1) 24 | { 25 | if (document.encoder.rem_jv.value * 1) 26 | { 27 | alphabet = 'ABCDEFGHIKLMNOPQRSTUWXYZ'; 28 | txt = Tr(txt, 'jJvV', 'iIuU'); 29 | } 30 | e.innerHTML = HTMLEscape(Baconian.encode(txt, alphabet)); 31 | } 32 | else 33 | { 34 | Timer.start(); 35 | var BACONIAN_ME = CURRENTSCRATCHPAD.realvalue; 36 | var digits = Binary.getDigitsIfBinary(CURRENTSCRATCHPAD.realvalue); 37 | var temp = false; 38 | if(!digits) { //If it isn't already in AB Baconian style, lets try other things 39 | if(BACONIAN_ME.length > 24 && (temp = BACONIAN_ME.match(/[a-z][A-Z]+[a-z]/g)) && temp.length > min_encoded_string_length) { //TODO: perform more input analysis here. 40 | BACONIAN_ME = BACONIAN_ME.replace( /([^a-zA-Z])/gi, '' ); 41 | BACONIAN_ME = BACONIAN_ME.replace( /([a-z])/g, '0' ); 42 | BACONIAN_ME = BACONIAN_ME.replace( /([A-Z])/g, '1' ); 43 | digits = Binary.getDigitsIfBinary(BACONIAN_ME); 44 | } else if((BACONIAN_ME.length%2 == 0 && /^(0x)?[0-9A-F]{2,}$/gi.test(BACONIAN_ME)) || 45 | (BACONIAN_ME.length%3 == 0 && /^([0-9A-F]{2}\ ){3,}$/gi.test(BACONIAN_ME))) { //Regular Hex but not binary//A9238BD88B5DC6E692E522D6EB5CE012891BCCE4BC88289277513167447744AE101C404340D40257BAAA556A54D752EA5B4AB5A916DB552B4B64AA5525AAB55D6AD25A9AB26C 46 | var temp = ConvertBaseSimple.hex2bin(Tr(BACONIAN_ME,' ')); 47 | if(digits = Binary.getDigitsIfBinary(temp)) { 48 | BACONIAN_ME = temp; 49 | } 50 | } 51 | } 52 | Timer.stop("Baconian - Prep"); 53 | /*if(/^(AAAAA|AABBA|ABBAA|BAABA|AAAAB|AABBB|ABBAB|BAABB|AAABA|ABAAA|ABBBA|BABAA|AAABB|ABAAB|ABBBB|BABAB|AABAA|ABABA|BAAAA|BABBA|AABAB|ABABB|BAAAB|BABBB)+$/gi) 54 | alert('hit');*/ 55 | 56 | if(digits/* && (digits[0] != 'A' || digits[1] != 'B')*/) 57 | { 58 | Timer.start(); 59 | txt = Binary.replaceBoth(BACONIAN_ME, digits[0], 'A', digits[1], 'B'); 60 | e.innerHTML = Teacher.analyzeValue(Baconian.decode(txt, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'baconian()')+'
'+ 61 | Teacher.analyzeValue(Baconian.decode(Tr(txt, 'jJvV', 'iIuU'), 'ABCDEFGHIKLMNOPQRSTUWXYZ'), 'baconian(\'remove jv\')')+'

'; 62 | txt = Binary.swap(txt); 63 | e.innerHTML+= Teacher.analyzeValue(Baconian.decode(txt, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'inverse().baconian()')+'
'+ 64 | Teacher.analyzeValue(Baconian.decode(Tr(txt, 'jJvV', 'iIuU'), 'ABCDEFGHIKLMNOPQRSTUWXYZ'), 'inverse().baconian(\'remove jv\')')+'
'; 65 | 66 | var o = document.getElementById('BACONIAN_output_reverse'); 67 | txt = T_ReverseText(txt); 68 | o.innerHTML = Teacher.analyzeValue(Baconian.decode(txt, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'reverse().inverse().baconian()')+'
'+ 69 | Teacher.analyzeValue(Baconian.decode(Tr(txt, 'jJvV', 'iIuU'), 'ABCDEFGHIKLMNOPQRSTUWXYZ'), 'reverse().inverse().baconian(\'remove jv\')')+'

'; 70 | txt = Binary.swap(txt); 71 | o.innerHTML+= Teacher.analyzeValue(Baconian.decode(txt, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'reverse().baconian()')+'
'+ 72 | Teacher.analyzeValue(Baconian.decode(Tr(txt, 'jJvV', 'iIuU'), 'ABCDEFGHIKLMNOPQRSTUWXYZ'), 'reverse().baconian(\'remove jv\')'); 73 | 74 | Timer.stop("Baconian - Eight"); 75 | } 76 | else 77 | { 78 | document.getElementById('BACONIAN_output_reverse').innerHTML = ''; 79 | } 80 | } 81 | 82 | //window.setTimeout('BACONIAN_upd()', 100); 83 | }, 84 | 85 | 86 | swapBaconian : function() 87 | { 88 | var s = CURRENTSCRATCHPAD.realvalue; 89 | var o = ''; 90 | 91 | for (var i = 0; i < s.length; i ++) 92 | { 93 | var c = s.charAt(i); 94 | if (c == '0') 95 | c = '1'; 96 | else if (c == '1') 97 | c = '0'; 98 | else if (c == 'a') 99 | c = 'b'; 100 | else if (c == 'b') 101 | c = 'a'; 102 | else if (c == 'A') 103 | c = 'B'; 104 | else if (c == 'B') 105 | c = 'A'; 106 | o += c; 107 | } 108 | 109 | CURRENTSCRATCHPAD.setRealValue(o); 110 | ForceFlow.updateEditedNode(CURRENTSCRATCHPAD); 111 | //ForceFlow.addSteps([Teacher.analyzeValueDoNotSaveGrade(o, 'baconian_swap()')]); 112 | //ForceFlow.selectFurthestSingleChildNodePath(); 113 | }, 114 | 115 | reverse : function() 116 | { 117 | var s = CURRENTSCRATCHPAD.realvalue; 118 | var i = s.length - 1, o = ''; 119 | 120 | while (i >= 0) 121 | { 122 | var c = s.charAt(i); 123 | if (c != "\r") 124 | o += c; 125 | i --; 126 | } 127 | 128 | CURRENTSCRATCHPAD.setRealValue(o); 129 | ForceFlow.updateEditedNode(CURRENTSCRATCHPAD); 130 | //ForceFlow.addSteps([Teacher.analyzeValueDoNotSaveGrade(o, 'baconian_reverse()')]); 131 | //ForceFlow.selectFurthestSingleChildNodePath(); 132 | }, 133 | 134 | encode : function(str, alphabet) 135 | { 136 | var spaceAdded = 1; 137 | var out = ''; 138 | 139 | str = str.toUpperCase(); 140 | alphabet = alphabet.toUpperCase(); 141 | 142 | for (var i = 0; i < str.length; i ++) 143 | { 144 | var c = str.charAt(i); 145 | var idx = alphabet.indexOf(c); 146 | if (idx >= 0) 147 | { 148 | out += (idx & 0x10)? 'B' : 'A'; 149 | out += (idx & 0x08)? 'B' : 'A'; 150 | out += (idx & 0x04)? 'B' : 'A'; 151 | out += (idx & 0x02)? 'B' : 'A'; 152 | out += (idx & 0x01)? 'B' : 'A'; 153 | spaceAdded = 0; 154 | } 155 | else 156 | { 157 | if (! spaceAdded) 158 | { 159 | out += ' '; 160 | spaceAdded = 1; 161 | } 162 | } 163 | } 164 | return out; 165 | }, 166 | 167 | 168 | decode : function(str, alphabet) 169 | { 170 | var out = ''; 171 | var buffer = ''; 172 | var addSpace = 0; 173 | 174 | str = str.toUpperCase(); 175 | str = Tr(str, '01', 'AB'); 176 | 177 | for (var i = 0; i < str.length; i ++) 178 | { 179 | var c = str.charAt(i); 180 | 181 | if (c == 'A' || c == 'B') 182 | { 183 | buffer += c; 184 | } 185 | else if (buffer == '') 186 | { 187 | addSpace = 1; 188 | } 189 | 190 | if (buffer.length == 5) 191 | { 192 | var idx = 0; 193 | 194 | idx += (buffer.charAt(0) == 'A')? 0 : 16; 195 | idx += (buffer.charAt(1) == 'A')? 0 : 8; 196 | idx += (buffer.charAt(2) == 'A')? 0 : 4; 197 | idx += (buffer.charAt(3) == 'A')? 0 : 2; 198 | idx += (buffer.charAt(4) == 'A')? 0 : 1; 199 | 200 | buffer = ''; 201 | 202 | if (addSpace) { 203 | out += ' '; 204 | addSpace = 0; 205 | } 206 | 207 | out += alphabet.charAt(idx); 208 | } 209 | } 210 | 211 | return out; 212 | } 213 | 214 | }; 215 | -------------------------------------------------------------------------------- /js/cipher/base58.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var ALPHABET, ALPHABET_MAP, Base58, i; 4 | 5 | Base58 = (typeof module !== "undefined" && module !== null ? module.exports : void 0) || (window.Base58 = {}); 6 | 7 | ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; 8 | 9 | ALPHABET_MAP = {}; 10 | 11 | i = 0; 12 | 13 | while (i < ALPHABET.length) { 14 | ALPHABET_MAP[ALPHABET.charAt(i)] = i; 15 | i++; 16 | } 17 | 18 | Base58.encode = function(buffer) { 19 | var carry, digits, j; 20 | if (buffer.length === 0) { 21 | return ""; 22 | } 23 | i = void 0; 24 | j = void 0; 25 | digits = [0]; 26 | i = 0; 27 | while (i < buffer.length) { 28 | j = 0; 29 | while (j < digits.length) { 30 | digits[j] <<= 8; 31 | j++; 32 | } 33 | digits[0] += buffer[i]; 34 | carry = 0; 35 | j = 0; 36 | while (j < digits.length) { 37 | digits[j] += carry; 38 | carry = (digits[j] / 58) | 0; 39 | digits[j] %= 58; 40 | ++j; 41 | } 42 | while (carry) { 43 | digits.push(carry % 58); 44 | carry = (carry / 58) | 0; 45 | } 46 | i++; 47 | } 48 | i = 0; 49 | while (buffer[i] === 0 && i < buffer.length - 1) { 50 | digits.push(0); 51 | i++; 52 | } 53 | return digits.reverse().map(function(digit) { 54 | return ALPHABET[digit]; 55 | }).join(""); 56 | }; 57 | 58 | Base58.decode = function(string) { 59 | var bytes, c, carry, j; 60 | if (string.length === 0) { 61 | return new(typeof Uint8Array !== "undefined" && Uint8Array !== null ? Uint8Array : Buffer)(0); 62 | } 63 | i = void 0; 64 | j = void 0; 65 | bytes = [0]; 66 | i = 0; 67 | while (i < string.length) { 68 | c = string[i]; 69 | if (!(c in ALPHABET_MAP)) { 70 | //throw "Base58.decode received unacceptable input. Character '" + c + "' is not in the Base58 alphabet."; 71 | return false; 72 | } 73 | j = 0; 74 | while (j < bytes.length) { 75 | bytes[j] *= 58; 76 | j++; 77 | } 78 | bytes[0] += ALPHABET_MAP[c]; 79 | carry = 0; 80 | j = 0; 81 | while (j < bytes.length) { 82 | bytes[j] += carry; 83 | carry = bytes[j] >> 8; 84 | bytes[j] &= 0xff; 85 | ++j; 86 | } 87 | while (carry) { 88 | bytes.push(carry & 0xff); 89 | carry >>= 8; 90 | } 91 | i++; 92 | } 93 | i = 0; 94 | while (string[i] === "1" && i < string.length - 1) { 95 | bytes.push(0); 96 | i++; 97 | } 98 | var output = new(typeof Uint8Array !== "undefined" && Uint8Array !== null ? Uint8Array : Buffer)(bytes.reverse()); 99 | return ByteArray.byteArrayToString(output); 100 | }; 101 | 102 | }).call(this); -------------------------------------------------------------------------------- /js/cipher/base64.js: -------------------------------------------------------------------------------- 1 | 2 | var Base64 = { 3 | // Base64 key string 4 | keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", 5 | 6 | upd : function() 7 | { 8 | if (IsUnchangedVar.text * IsUnchangedVar.encdec) 9 | { 10 | //window.setTimeout('BASE64_upd()', 100); 11 | return; 12 | } 13 | 14 | //ResizeTextArea(CURRENTSCRATCHPAD); 15 | 16 | var e = document.getElementById('BASE64_output'); 17 | 18 | if (CURRENTSCRATCHPAD.realvalue == '') 19 | { 20 | e.innerHTML = 'Enter your text and see the converted message here!'; 21 | } 22 | else 23 | { 24 | Timer.start(); 25 | var decodedvalue = Base64.calc(document.encoder.encdec.value * 1, CURRENTSCRATCHPAD.realvalue); 26 | //alert(1); 27 | if (decodedvalue) { 28 | //alert(2); 29 | //e.innerHTML = Guesses.analyzeGuessAndGradeValue([decodedvalue, CertaintyEnum.DESPERATE], 'base64()'); 30 | e.innerHTML = Teacher.analyzeValue(decodedvalue, 'base64()'); //SwapSpaces(HTMLEscape( 31 | } 32 | 33 | 34 | 35 | if(/^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}(==)?|[A-Z0-9+\/]{3}=?)?$/i.test(CURRENTSCRATCHPAD.realvalue) || //Not else if because base32 is sometimes also tried if padding is missing 36 | /^(?:(==)?[A-Z0-9+\/]{2}|=?[A-Z0-9+\/]{3})?(?:[A-Z0-9+\/]{4})*$/i.test(CURRENTSCRATCHPAD.realvalue)) //Base64 or reverse(Base64) missing = padding compatible 37 | { 38 | var decodedvalue = /*DEPRECATED:ByteArray.byteArrayToHex(ByteArray.stringToByteArray*/ConvertBase.strToHex(Base64.b64_to_utf8_hex(CURRENTSCRATCHPAD.realvalue)); 39 | if(decodedvalue && Global.InputType >= InputTypeEnum.ALPHANUMERIC && !Binary.getDigitsIfBinary(CURRENTSCRATCHPAD.realvalue)) { 40 | Guesses.saveGuess(CertaintyEnum.DESPERATE, decodedvalue, 'base64ToHex()'); //Let's hope we never need to use this value 41 | } 42 | document.getElementById('BASE64_hex_output').innerHTML = Teacher.analyzeValue(decodedvalue, 'base64toHex()'); 43 | } 44 | 45 | Timer.stop("Base64 - Two"); 46 | } 47 | 48 | //window.setTimeout('BASE64_upd()', 100); 49 | }, 50 | 51 | calc : function(encdec, textstr) { 52 | var temp = Base64.calculate(encdec, textstr); 53 | if(temp/* && /^[0-9A-Za-z\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\`\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]*$/.test(temp.slice(0, -2)) && //remove last 2 chars in case padding = is missing 54 | !(/[\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\`\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]{4,}/.test(temp.slice(0, -2)))*/) { 55 | return temp; 56 | } 57 | temp = Base64.calculate(encdec, T_ReverseText(textstr)); 58 | if(temp/* && /^[0-9A-Za-z\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\`\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]*$/.test(temp.slice(0, -2)) && 59 | !(/[\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\`\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]{4,}/.test(temp.slice(0, -2)))*/) { 60 | return temp; 61 | } 62 | return false; 63 | }, 64 | 65 | calcGetSteps : function(encdec, text) 66 | { 67 | var temp = Base64.calculate(encdec, text); 68 | if(temp/* && /^[0-9A-Za-z\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\`\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]*$/.test(temp.slice(0, -2)) && //remove last 2 chars in case padding = is missing 69 | !(/[\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\`\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]{4,}/.test(temp.slice(0, -2)))*/) { 70 | return [Teacher.analyzeValueDoNotSaveGrade(temp, 'base64()')]; 71 | } 72 | temp = Base64.calculate(encdec, T_ReverseText(text)); 73 | if(temp/* && /^[0-9A-Za-z\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\`\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]*$/.test(temp.slice(0, -2)) && 74 | !(/[\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\`\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]{4,}/.test(temp.slice(0, -2)))*/) { 75 | return [Teacher.analyzeValueDoNotSaveGrade(T_ReverseText(text), 'reverse()'),Teacher.analyzeValueDoNotSaveGrade(temp, 'base64()')]; 76 | } 77 | return false; 78 | }, 79 | 80 | // Wrapper for standard interface 81 | // https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64.btoa 82 | calculate : function(encdec, textstr) { 83 | if (encdec > 0) { 84 | //return Base64.encode(textstr); 85 | return Base64.utf8_to_b64(textstr); 86 | //return window.btoa(textstr); 87 | } 88 | //return Base64.decode(textstr); 89 | return Base64.b64_to_utf8(textstr); 90 | //return window.atob(textstr); 91 | }, 92 | // Usage: 93 | //utf8_to_b64('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU=" 94 | //b64_to_utf8('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode" 95 | utf8_to_b64 : function( str ) { 96 | try { 97 | return window.btoa(unescape(encodeURIComponent( str ))); 98 | } catch(e) { 99 | return false; 100 | } 101 | }, 102 | b64_to_utf8 : function( str ) { 103 | try { 104 | return decodeURIComponent(escape(window.atob( str ))); 105 | } catch(e) { 106 | try { 107 | return window.atob( str ); 108 | } catch(e) {} 109 | return false; 110 | } 111 | }, 112 | b64_to_utf8_hex : function( str ) { 113 | try { 114 | return window.atob( str ); 115 | } catch(e) { 116 | return false; 117 | } 118 | }, 119 | 120 | encode : function (input) { 121 | var output = ""; 122 | var chr1, chr2, chr3; 123 | var enc1, enc2, enc3, enc4; 124 | var i = 0; 125 | 126 | do { 127 | chr1 = input.charCodeAt(i++); 128 | chr2 = input.charCodeAt(i++); 129 | chr3 = input.charCodeAt(i++); 130 | 131 | enc1 = chr1 >> 2; 132 | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 133 | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 134 | enc4 = chr3 & 63; 135 | 136 | if (isNaN(chr2)) { 137 | enc3 = enc4 = 64; 138 | } else if (isNaN(chr3)) { 139 | enc4 = 64; 140 | } 141 | 142 | output = output + this.keyStr.charAt(enc1) + this.keyStr.charAt(enc2) + 143 | this.keyStr.charAt(enc3) + this.keyStr.charAt(enc4); 144 | } while (i < input.length); 145 | 146 | return output; 147 | }, 148 | 149 | decode : function (input) { 150 | var output = ""; 151 | var chr1, chr2, chr3; 152 | var enc1, enc2, enc3, enc4; 153 | var i = 0; 154 | 155 | // remove all characters that are not A-Z, a-z, 0-9, +, /, or = 156 | input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 157 | 158 | while (i < input.length) { 159 | enc1 = this.keyStr.indexOf(input.charAt(i++)); 160 | enc2 = this.keyStr.indexOf(input.charAt(i++)); 161 | enc3 = this.keyStr.indexOf(input.charAt(i++)); 162 | enc4 = this.keyStr.indexOf(input.charAt(i++)); 163 | 164 | chr1 = (enc1 << 2) | (enc2 >> 4); 165 | chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 166 | chr3 = ((enc3 & 3) << 6) | enc4; 167 | 168 | output = output + String.fromCharCode(chr1); 169 | 170 | if (enc3 != 64) { 171 | output = output + String.fromCharCode(chr2); 172 | } 173 | if (enc4 != 64) { 174 | output = output + String.fromCharCode(chr3); 175 | } 176 | } 177 | 178 | return output; 179 | } 180 | 181 | 182 | /*decode : function(textstr) { 183 | var temp = calc_decode(textstr); 184 | if(/^[0-9A-Za-z\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\`\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]*$/.test(temp.slice(0, -2)) && //remove last 2 chars in case padding = is missing 185 | !(/[\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]{4,}/.test(temp.slice(0, -2)))) { 186 | return temp; 187 | } 188 | temp = calc_decode(T_ReverseText(textstr)); 189 | if(/^[0-9A-Za-z\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\`\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]*$/.test(temp.slice(0, -2)) && 190 | !(/[\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\,\<\.\>\/\?\-\_\=\+\~\\\r\n ]{4,}/.test(temp.slice(0, -2)))) { 191 | return temp; 192 | } 193 | return false; 194 | }*/ 195 | }; 196 | -------------------------------------------------------------------------------- /js/cipher/baudotmurray.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var BaudotMurray = { 4 | 5 | codes : { 6 | '00011': ['a', '-'], 7 | '11001': ['b', '?'], 8 | '01110': ['c', ':'], 9 | '01001': ['d', 'Who\'s there?'], 10 | '00001': ['e', '3'], 11 | '01101': ['f', undefined], 12 | '11010': ['g', undefined], 13 | '10100': ['h', undefined], 14 | '00110': ['i', '8'], 15 | '01011': ['j', '*bell*'], 16 | '01111': ['k', '('], 17 | '10010': ['l', ')'], 18 | '11100': ['m', '.'], 19 | '01100': ['n', ','], 20 | '11000': ['o', '9'], 21 | '10110': ['p', '0'], 22 | '10111': ['q', '1'], 23 | '01010': ['r', '4'], 24 | '00101': ['s', "'"], 25 | '10000': ['t', '5'], 26 | '00111': ['u', '7'], 27 | '11110': ['v', '='], 28 | '10011': ['w', '2'], 29 | '11101': ['x', '/'], 30 | '10101': ['y', '6'], 31 | '10001': ['z', '+'], 32 | '01000': ["\n", "\n"], 33 | '00010': ["\t", "\t"], 34 | '00100': [' ', ' '], 35 | '11111': ['letters', 'letters'], 36 | '11011': ['figures', 'figures'] 37 | }, 38 | 39 | upd : function() { 40 | if (IsUnchangedVar.text || CURRENTSCRATCHPAD.realvalue == '') { 41 | return; 42 | } else { 43 | 44 | Timer.start(); 45 | var digits = Binary.getDigitsIfBinary(CURRENTSCRATCHPAD.realvalue); 46 | try { 47 | if(digits) { 48 | var temp = BaudotMurray.calcDecodeBaudotMurrayGetSteps(Binary.replaceBoth(CURRENTSCRATCHPAD.realvalue, digits[0], '0', digits[1], '1'), true); 49 | if(temp && temp.length && temp[0].value) { 50 | var certainty = REGEX_POSSIBLEFLAGCHARS.test(temp[0].value)?CertaintyEnum.WILDGUESS:CertaintyEnum.DESPERATE; 51 | document.getElementById('ASCII_baudotmurray').innerHTML = Guesses.analyzeGuessAndGradeValue([temp[0].value, certainty], 'baudot_murray()'); 52 | } 53 | } 54 | } catch(e) {} 55 | 56 | Timer.stop("BaudotMurray - Single"); 57 | } 58 | }, 59 | 60 | calcDecodeBaudotMurrayGetSteps : function(originaltext, noOutputValidation) 61 | { 62 | 63 | var text; 64 | var digits = Binary.getDigitsIfBinary(originaltext); 65 | noOutputValidation = (typeof noOutputValidation == "undefined")? false : noOutputValidation; 66 | if(digits) { 67 | originaltext = originaltext.replace(/[ \r\n]+/g, ""); 68 | if(digits[0] != '0' || digits[1] != '1') { 69 | alert('calcDecodeBaudotMurrayGetSteps(input) should run with 0\'s and 1\'s. Use decodeBinary instead'); 70 | } 71 | eval("text = originaltext.replace(/(["+digits[0]+''+digits[1]+"]{5})/g, '$& ');"); 72 | var res = BaudotMurray.calc(text.split(' ')); 73 | if(res && (REGEX_FILE_TYPES.test(res) || REGEX_TEXTNUMBERSSPECIALCHARS.test(res) || noOutputValidation)) { 74 | return [Teacher.analyzeValueDoNotSaveGrade(res, 'baudot_murray()')]; 75 | //return res; 76 | } else { 77 | return false; 78 | } 79 | } 80 | return false; 81 | }, 82 | 83 | calc : function(text) 84 | { 85 | var ita2Code = BaudotMurray.codes; 86 | 87 | // shift 88 | var letterShift = true; 89 | var output = ''; 90 | 91 | // go through splitted content 92 | for (var i = 0; i < text.length && text[i].length; i ++) 93 | { 94 | var entry = text[i]; 95 | var row = ita2Code[entry]; 96 | 97 | if (row != undefined) 98 | { 99 | var ita2Entry = row[letterShift ? 0 : 1]; 100 | 101 | if (ita2Entry == undefined) 102 | return false; 103 | else if (ita2Entry == 'letters') 104 | letterShift = true; 105 | else if (ita2Entry == 'figures') 106 | letterShift = false; 107 | else 108 | output += ita2Entry; 109 | } 110 | else 111 | return false; 112 | } 113 | return output; 114 | }, 115 | }; -------------------------------------------------------------------------------- /js/cipher/bifid.js: -------------------------------------------------------------------------------- 1 | 2 | var Bifid = { 3 | 4 | upd : function() 5 | { 6 | var keyunchanged = IsUnchangedVar.BIFID_skip * IsUnchangedVar.BIFID_key; 7 | 8 | if (keyunchanged == 0) 9 | { 10 | // Update the rectangle 11 | var k, elem; 12 | 13 | k = MakeKeyedAlphabet(document.encoder.BIFID_skip.value + document.encoder.BIFID_key.value); 14 | k = k.slice(1, k.length); 15 | elem = document.getElementById('BIFID_alphabet'); 16 | elem.innerHTML = HTMLTableau(k); 17 | } 18 | 19 | if (keyunchanged * IsUnchangedVar.text * IsUnchangedVar.encdec * IsUnchangedVar.BIFID_skipto) 20 | { 21 | //window.setTimeout('BIFID.upd()', 100); 22 | return; 23 | } 24 | 25 | //ResizeTextArea(CURRENTSCRATCHPAD); 26 | 27 | var elem = document.getElementById('BIFID_output'); 28 | 29 | if (CURRENTSCRATCHPAD.realvalue != "") 30 | { 31 | Timer.start(); 32 | elem.innerHTML = Bifid.calc(document.encoder.encdec.value * 1, 33 | CURRENTSCRATCHPAD.realvalue, document.encoder.BIFID_skip.value, 34 | document.encoder.BIFID_skipto.value, document.encoder.BIFID_key.value); 35 | Teacher.analyzeField("BIFID_output", 'bifid()'); 36 | Timer.stop("Bifid - Single"); 37 | 38 | Timer.start(); 39 | o = document.getElementById('BIFID_output_bruteF'); 40 | var out = ''; 41 | var passwords = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']; 42 | passwords = passwords.concat(brute_force_dictionary_keys); 43 | var encdec = document.encoder.encdec.value * 1; 44 | for(var i = 0; i < passwords.length; i++) { 45 | var r = Bifid.calc(encdec, 46 | CURRENTSCRATCHPAD.realvalue, document.encoder.BIFID_skip.value, 47 | document.encoder.BIFID_skipto.value, passwords[i]); 48 | r = encdec < 0?Guesses.analyzeValueSavePWGuess(r, passwords[i], 'bifid('+passwords[i]+','+document.encoder.BIFID_skip.value+','+document.encoder.BIFID_skipto.value+')'):r; 49 | out += 'Pass: '+passwords[i]+': '+r+"
\n"; 50 | } 51 | o.innerHTML = out; 52 | Timer.stop("Bifid - BruteF over "+passwords.length); 53 | } 54 | else 55 | { 56 | elem.innerHTML = "Type in your message and see the results here!"; 57 | } 58 | 59 | //window.setTimeout('BIFID.upd()', 100); 60 | }, 61 | 62 | // Bifid Cipher 63 | 64 | // This code was written by Tyler Akins and is placed in the public domain. 65 | // It would be nice if this header remained intact. http://rumkin.com 66 | 67 | // Requires util.js 68 | 69 | 70 | // Performs a Bifid cipher on the passed-in text 71 | // encdec = -1 for decode, 1 for encode 72 | // text = the text to encode/decode 73 | // skip = the letter omitted from the 5x5 grid 74 | // skipto = what the "skip" letter should be translated to before encoding 75 | // key = the word or phrase used to generate letter placement in the 5x5 grid 76 | calc : function(encdec, text, skip, skipto, key) 77 | { 78 | var enc, out, bet, otemp, c; 79 | 80 | if (typeof(skip) != 'string' || skip.length != 1 || 81 | skip.toUpperCase() < 'A' || skip.toUpperCase() > 'Z') 82 | skip = "J"; 83 | skip = skip.toUpperCase(); 84 | 85 | if (typeof(skipto) != 'string' || skipto.length != 1 || 86 | skipto.toUpperCase() < 'A' || skipto.toUpperCase() > 'Z') 87 | skipto = "I"; 88 | skipto = skipto.toUpperCase(); 89 | 90 | if (skip == skipto) 91 | { 92 | skipto = String.fromCharCode(skip.charCodeAt(0) + 1); 93 | if (skipto > 'Z') 94 | skipto = 'A'; 95 | } 96 | 97 | if (typeof(key) != 'string') 98 | key = ""; 99 | 100 | key = MakeKeyedAlphabet(skip + key); 101 | key = key.slice(1, key.length); 102 | 103 | enc = ''; 104 | out = ''; 105 | bet = ''; 106 | for (var i = 0; i < text.length; i ++) 107 | { 108 | c = text.charAt(i).toUpperCase(); 109 | if (c == skip) 110 | c = skipto; 111 | 112 | if (key.indexOf(c) >= 0) 113 | { 114 | enc += c; 115 | } 116 | } 117 | enc = Bifid.mangle(encdec, enc, key) 118 | 119 | for (var i = 0, j = 0; i < text.length; i ++) 120 | { 121 | c = text.charAt(i).toUpperCase(); 122 | if (c == skip) 123 | c = skipto; 124 | 125 | if (key.indexOf(c) >= 0) 126 | { 127 | if (text.charAt(i) != text.charAt(i).toUpperCase()) 128 | { 129 | out += enc.charAt(j).toLowerCase(); 130 | } 131 | else 132 | { 133 | out += enc.charAt(j); 134 | } 135 | j ++; 136 | } 137 | else 138 | { 139 | out += text.charAt(i); 140 | } 141 | } 142 | 143 | return out; 144 | }, 145 | 146 | only_letters : function() 147 | { 148 | ForceFlow.addSteps([Teacher.analyzeValueDoNotSaveGrade(OnlyAlpha(CURRENTSCRATCHPAD.realvalue), 'bifid_only_letters()')]); 149 | ForceFlow.selectFurthestSingleChildNodePath(); 150 | }, 151 | 152 | 153 | example_enc: function() 154 | { 155 | document.encoder.encdec.value = 1; 156 | document.encoder.BIFID_skip.value = "J"; 157 | document.encoder.BIFID_skipto.value = "I"; 158 | document.encoder.BIFID_key.value = ""; 159 | ForceFlow.addSteps([Teacher.analyzeValueDoNotSaveGrade("ABCD", 'bifid_example()')]); 160 | ForceFlow.selectFurthestSingleChildNodePath(); 161 | }, 162 | 163 | 164 | wikipedia_enc : function() 165 | { 166 | document.encoder.encdec.value = 1; 167 | document.encoder.BIFID_skip.value = "J"; 168 | document.encoder.BIFID_skipto.value = "I"; 169 | document.encoder.BIFID_key.value = "BGWKZQPNDSIOAXEFCLUMTHYVR"; 170 | ForceFlow.addSteps([Teacher.analyzeValueDoNotSaveGrade("F L E E A T O N C E", 'bifid_wiki_example()')]); 171 | ForceFlow.selectFurthestSingleChildNodePath(); 172 | }, 173 | 174 | // Performs the actual encoding/decoding of the text 175 | // Chars must only contain characters in 'key', case sensitive 176 | // Key must be the letters from a 5x5 grid. 177 | mangle : function(encdec, chars, key) 178 | { 179 | var pos, line1, line2; 180 | 181 | line1 = ''; 182 | line2 = ''; 183 | 184 | for (var i = 0; i < chars.length; i ++) 185 | { 186 | var row, col; 187 | 188 | pos = key.indexOf(chars.charAt(i)); 189 | row = Math.floor(pos / 5); 190 | col = pos % 5; 191 | 192 | line1 += row; 193 | if (encdec > 0) 194 | { 195 | line2 += col; 196 | } 197 | else 198 | { 199 | line1 += col; 200 | } 201 | } 202 | 203 | line1 += line2; 204 | 205 | if (encdec < 0) 206 | { 207 | line2 = ''; 208 | for (var i = 0; i < line1.length / 2; i ++) 209 | { 210 | line2 += line1.charAt(i); 211 | line2 += line1.charAt(line1.length / 2 + i); 212 | } 213 | window.status = line1 + " " + line2; 214 | line1 = line2; 215 | } 216 | 217 | chars = ''; 218 | 219 | for (var i = 0; i < line1.length; i += 2) 220 | { 221 | chars += key.charAt(line1.charAt(i) * 5 + line1.charAt(i + 1) * 1); 222 | } 223 | 224 | return chars; 225 | } 226 | 227 | }; 228 | -------------------------------------------------------------------------------- /js/cipher/bytearray.js: -------------------------------------------------------------------------------- 1 | 2 | var ByteArray = { 3 | 4 | fill : function(value, len) { 5 | var arr = []; 6 | for (var i = 0; i < len; i++) { 7 | arr.push(value); 8 | } 9 | return arr; 10 | }, 11 | 12 | stringToByteArray : function(string) 13 | { 14 | if(string) { 15 | var byteArray = new Array(string.length); 16 | for (var i=0; i= 'a') return c.charCodeAt(0) - 87; 52 | if (c >= 'A') return c.charCodeAt(0) - 55; 53 | if (c >= '0') return c.charCodeAt(0) - 48; 54 | return -1; 55 | }, 56 | 57 | hexToByteArray : function(hexString) 58 | { 59 | var byteArray = new Array(); 60 | var upper4 = true; 61 | var o=0; 62 | for (var i=0; i> 4) & 15) + hexdigits.charAt(byteArray[i] & 15); 83 | } 84 | return hexString; 85 | }, 86 | 87 | string2Hex : function(element, reverse) //element = document.getElementById(id) or document.encoder.xor_a 88 | { 89 | if (reverse) 90 | element.value = ByteArray.byteArrayToString(ByteArray.hexToByteArray(document.getElementById(id).value)); 91 | else 92 | element.value = ByteArray.byteArrayToHex(ByteArray.stringToByteArray(document.getElementById(id).value)); 93 | }, 94 | 95 | getByteArray : function(element, fromstring) //element = document.getElementById(id) or document.encoder.xor_a 96 | { 97 | if (fromstring) 98 | return ByteArray.stringToByteArray(element); 99 | else 100 | return ByteArray.hexToByteArray(element); 101 | } 102 | }; -------------------------------------------------------------------------------- /js/cipher/code39.js: -------------------------------------------------------------------------------- 1 | 2 | var Code39 = { 3 | 4 | 5 | upd : function() 6 | { 7 | if (IsUnchangedVar.text) 8 | { 9 | return; 10 | } 11 | 12 | var e = document.getElementById('CODE39_output'); 13 | 14 | if (CURRENTSCRATCHPAD.realvalue != '') 15 | { 16 | Timer.start(); 17 | //ttwtttwwtt wtttwttwtt twwtttwttt wwttwttttt wtttwttwtt wwttttttwt twwtttwttt wttttttwwt ttttwttwwt wtttwttwtt wwwttttttt twwtttwttt wwwttttttt wttttwwttt wttttwttwt ttttwtwwtt twwtttwttt wtwttwtttt wtttwttwtt ttttwwttwt wtttwwtttt wtwwtttttt ttwwttwttt twwtttwttt ttwttttwwt wtttwttwtt wtttwttwtt wttttttwwt ttwtttwwtt twwtttwttt ttwttttwwt ttwttwwttt wttttttwwt wtttwwtttt wwttttwttt 18 | var ret = Code39.decodeCode39GetSteps(CURRENTSCRATCHPAD.realvalue, true); 19 | if(ret && $.isArray(ret) && ret.length>0) { 20 | e.innerHTML = Teacher.analyzeValue(ret[ret.length-1].value, 'code39()'); 21 | } 22 | Timer.stop("Code39 (barcode) - Double"); 23 | } 24 | }, 25 | 26 | decodeCode39GetSteps : function(originaltext, noOutputValidation) //With autochecker for auto binary check 27 | { 28 | var text = originaltext.replace(/\s/g,''); 29 | noOutputValidation = (typeof noOutputValidation == "undefined")? false : noOutputValidation; 30 | if (text.length >= 30 && text.replace(/\s/g,'').length%10 == 0) //ttttwtwwtt wtttwwtttt ttwtttwwtt ttttwtwwtt wttwttttwt //TEST1 31 | { 32 | var digits = Binary.getDigitsIfBinary(text); 33 | if(digits) { 34 | var possibleCode39 = Binary.replaceBoth(text, digits[0], '0', digits[1], '1'); 35 | var zeros = possibleCode39.match(/0/g); 36 | var ones = possibleCode39.match(/1/g); 37 | if(zeros && ones) { 38 | var nrzeros = zeros.length; 39 | var nrones = ones.length; 40 | if( (nrzeros%7 == 0 && nrones%3 == 0 && nrzeros/7 == nrones/3) || (nrzeros%3 == 0 && nrones%7 == 0 && nrzeros/3 == nrones/7) ) 41 | { 42 | //alert('Code39 found. It matches (#0)/3 == (#1)/7 or vise versa exactly. So certainty is high.'); 43 | var code39input = ''; 44 | if(nrzeros%7 == 0 && nrones%3 == 0 && nrzeros/7 == nrones/3) { 45 | code39input = Binary.replaceBoth(text, digits[0], 't', digits[1], 'w'); 46 | } else if(nrzeros%3 == 0 && nrones%7 == 0 && nrzeros/3 == nrones/7) { 47 | code39input = Binary.replaceBoth(text, digits[0], 't', digits[1], 'w'); 48 | } else { 49 | alert('How did I get here @checkAllDecodings() @ code39?'); 50 | } 51 | 52 | var output = Code39.calc(code39input); 53 | if(noOutputValidation) { 54 | return output; 55 | } else if(output && $.isArray(output) && output.length>0) { 56 | var temp = output[output.length-1].value; 57 | if(/^[0-9A-Z\-\.\ \*\$\/\+\%]+$/.test(temp) && ! /tw/g.test(temp)) { 58 | return output; 59 | } 60 | } else { 61 | alert('Code39 found but could not decode somehow. It matches (#0)/3 == (#1)/7 or vise versa exactly. So certainty is still high. Try Code39.decodeCode39GetSteps(input, true); to skip output validation.'); 62 | } 63 | return false; 64 | } 65 | } 66 | } 67 | } 68 | return false; 69 | }, 70 | 71 | /*function decodeCode39(originaltext) //With autochecker for auto binary check 72 | { 73 | var digits = Binary.getDigitsIfBinary(originaltext); 74 | return calcDecodeCode39GetResult(Binary.replaceBoth(originaltext, digits[0], '0', digits[1], '1')); 75 | }, 76 | 77 | function decodeCode39GetStepsNoChecks(originaltext) //With autochecker for auto binary check 78 | { 79 | var digits = Binary.getDigitsIfBinary(originaltext); 80 | return this.calc(Binary.replaceBoth(originaltext, digits[0], 't', digits[1], 'w')); 81 | }, 82 | 83 | function calcDecodeCode39GetResult(originaltext) 84 | { 85 | var ret = Code39.calc(originaltext); 86 | if(ret && $.isArray(ret) && ret.length>0){ 87 | return ret[ret.length-1].value; 88 | } 89 | return false; 90 | },*/ 91 | 92 | calc : function(text) 93 | { 94 | var temp = text.replace(/\s/g,'').match(/(..........?)/g).join('@'); 95 | var mapObj = { 96 | 'wttwttttwt' : '1', 97 | 'ttwwttttwt' : '2', 98 | 'wtwwtttttt' : '3', 99 | 'tttwwtttwt' : '4', 100 | 'wttwwttttt' : '5', 101 | 'ttwwwttttt' : '6', 102 | 'tttwttwtwt' : '7', 103 | 'wttwttwttt' : '8', 104 | 'ttwwttwttt' : '9', 105 | 'tttwwtwttt' : '0', 106 | 'wttttwttwt' : 'A', 107 | 'ttwttwttwt' : 'B', 108 | 'wtwttwtttt' : 'C', 109 | 'ttttwwttwt' : 'D', 110 | 'wtttwwtttt' : 'E', 111 | 'ttwtwwtttt' : 'F', 112 | 'tttttwwtwt' : 'G', 113 | 'wttttwwttt' : 'H', 114 | 'ttwttwwttt' : 'I', 115 | 'ttttwwwttt' : 'J', 116 | 'wttttttwwt' : 'K', 117 | 'ttwttttwwt' : 'L', 118 | 'wtwttttwtt' : 'M', 119 | 'ttttwttwwt' : 'N', 120 | 'wtttwttwtt' : 'O', 121 | 'ttwtwttwtt' : 'P', 122 | 'ttttttwwwt' : 'Q', 123 | 'wtttttwwtt' : 'R', 124 | 'ttwtttwwtt' : 'S', 125 | 'ttttwtwwtt' : 'T', 126 | 'wwttttttwt' : 'U', 127 | 'twwtttttwt' : 'V', 128 | 'wwwttttttt' : 'W', 129 | 'twttwtttwt' : 'X', 130 | 'wwttwttttt' : 'Y', 131 | 'twwtwttttt' : 'Z', 132 | 'twttttwtwt' : '-', 133 | 'wwttttwttt' : '.', 134 | 'twwtttwttt' : ' ', 135 | 'twttwtwttt' : '*', 136 | 'twtwtwtttt' : '$', 137 | 'twtwtttwtt' : '/', 138 | 'twtttwtwtt' : '+', 139 | 'tttwtwtwtt' : '%', 140 | }; 141 | 142 | var output = null; 143 | var reversed = false; 144 | while(true) 145 | { 146 | output = temp.replace(/wttwttttwt|ttwwttttwt|wtwwtttttt|tttwwtttwt|wttwwttttt|ttwwwttttt|tttwttwtwt|wttwttwttt|ttwwttwttt|tttwwtwttt|wttttwttwt|ttwttwttwt|wtwttwtttt|ttttwwttwt|wtttwwtttt|ttwtwwtttt|tttttwwtwt|wttttwwttt|ttwttwwttt|ttttwwwttt|wttttttwwt|ttwttttwwt|wtwttttwtt|ttttwttwwt|wtttwttwtt|ttwtwttwtt|ttttttwwwt|wtttttwwtt|ttwtttwwtt|ttttwtwwtt|wwttttttwt|twwtttttwt|wwwttttttt|twttwtttwt|wwttwttttt|twwtwttttt|twttttwtwt|wwttttwttt|twwtttwttt|twttwtwttt|twtwtwtttt|twtwtttwtt|twtttwtwtt|tttwtwtwtt/gi, function(matched){ return mapObj[matched]; }).replace(/@/g,''); 147 | if(output.length < (text.length>>1) ) { //Decoded it :) break and return 148 | if( ! reversed ) output = [Teacher.analyzeValueDoNotSaveGrade(output, 'code39()')]; 149 | else output = [Teacher.analyzeValueDoNotSaveGrade(T_ReverseString(text), 'reverse()'), Teacher.analyzeValueDoNotSaveGrade(output, 'code39()')]; 150 | break; 151 | } else if(output.length >= (text.length>>1) && !reversed) { //Let's reverse the input once! 152 | temp = T_ReverseString(temp); 153 | reversed = true; 154 | continue; 155 | } else { //Even reversing it didn't work... :( Let's return false; 156 | output = false; 157 | break; 158 | } 159 | } 160 | return output; 161 | }, 162 | 163 | }; 164 | 165 | -------------------------------------------------------------------------------- /js/cipher/ebcdic.js: -------------------------------------------------------------------------------- 1 | 2 | var Ebcdic = { 3 | //http://www.toptip.ca/2011/01/ascii-ebcdic-online-converter.html 4 | asciiList : [ 5 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 6 | 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 7 | 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 8 | 9 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 10 | 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 11 | 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 12 | 13 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 14 | 15 | ' ', '.', '<', '(', '+', '|', 16 | '!', '$', '*', ')', ';', '-', 17 | ',', '%', '_', '>', '?', 18 | ':', '#', '@', "'", '=', '"','', 19 | ], 20 | 21 | ebcdicList : [ 22 | '81','82','83','84','85','86','87','88','89', 23 | '91','92','93','94','95','96','97','98','99', 24 | 'A2','A3','A4','A5','A6','A7','A8','A9', 25 | 26 | 'C1','C2','C3','C4','C5','C6','C7','C8','C9', 27 | 'D1','D2','D3','D4','D5','D6','D7','D8','D9', 28 | 'E2','E3','E4','E5','E6','E7','E8','E9', 29 | 30 | 'F0','F1','F2','F3','F4','F5','F6','F7','F8','F9', 31 | 32 | '40','4B','4C','4D','4E','4F', 33 | '5A','5B','5C','5D','5E','5F', 34 | '6B','6C','6D','6E','6F', 35 | '7A','7B','7C','7D','7E','7F','00', 36 | ], 37 | 38 | upd : function() 39 | { 40 | if (IsUnchangedVar.text) 41 | { 42 | return; 43 | } 44 | 45 | var e = document.getElementById('EBCDIC_output'); 46 | 47 | if (CURRENTSCRATCHPAD.realvalue != '') 48 | { 49 | Timer.start(); 50 | var text = CURRENTSCRATCHPAD.realvalue; 51 | if(text.length%2 == 0 && /^([0-9A-F][0-9A-F]){2,}$/gi.test(text)) 52 | text = text.match(/(..?)/g).join(' '); 53 | e.innerHTML = Teacher.analyzeValue(Ebcdic.ebcdic2ascii(text, true), 'ebcdic()'); 54 | Timer.stop("Ebcdic - Single"); 55 | } 56 | }, 57 | 58 | decode : function(input) 59 | { 60 | return Ebcdic.ebcdic2ascii(input, false); 61 | }, 62 | decodeGetSteps : function(input) 63 | { 64 | var temp = Ebcdic.ebcdic2ascii(input, false); 65 | if(temp) 66 | return [Teacher.analyzeValueDoNotSaveGrade(temp, 'ebcdic()')]; 67 | return false; 68 | }, 69 | ebcdic2ascii : function(input,errormsg) 70 | { 71 | var output = ''; 72 | 73 | // convert "\xC1\x82\x83\xF1" to "C1 82 83 F1" 74 | ebcd_s = input.replace(/\\x/g, " ").replace(/[\!\@\#\$\%\^\&\|\*\(\)\{\}\[\]\;\:\'\"\,\<\.\>\/\?\-\_\=\+\~\\]/g, " "); 75 | ebcd_s = ebcd_s.replace(/^\s+|\s+$/g, ""); // trim spaces 76 | 77 | var ebcd_a = ebcd_s.split(" "); // e.g. C1 82 83 F1 78 | 79 | for (var i = 0; i < ebcd_a.length; i++) 80 | { 81 | var c = ebcd_a[i]; 82 | 83 | var found = false; 84 | for (var j = 0; j < this.ebcdicList.length; j++) 85 | { 86 | if (c == this.ebcdicList[j]) 87 | { 88 | output += this.asciiList[j]; 89 | found = true; 90 | break; 91 | } 92 | } 93 | 94 | if (!found) 95 | { 96 | //alert("Error: Cannot convert " + c + " at position: " + i); 97 | return errormsg?('Error: Cannot convert at position: Char:'+c+' position' + i + ''):false;//false; 98 | } 99 | } 100 | return output; 101 | }, 102 | 103 | encode : function(input) 104 | { 105 | return Ebcdic.ascii2ebcdic(input, false); 106 | }, 107 | ascii2ebcdic : function(input,errormsg) 108 | { 109 | var output = ''; 110 | 111 | for (var i = 0; i < input.length; i++) 112 | { 113 | var c = input[i]; 114 | 115 | var found = false; 116 | for (var j = 0; j < this.asciiList.length; j++) 117 | { 118 | if (c == this.asciiList[j]) 119 | { 120 | output += "\\x" + this.ebcdicList[j]; 121 | found = true; 122 | break; 123 | } 124 | } 125 | 126 | if (!found) 127 | { 128 | //alert("Error: Cannot convert " + c + " at position: " + i); 129 | return errormsg?('Error: Cannot convert at position: Char:'+c+' position' + i + ''):false;//false; 130 | } 131 | } 132 | return output; 133 | } 134 | }; 135 | 136 | -------------------------------------------------------------------------------- /js/cipher/enigma/base.js: -------------------------------------------------------------------------------- 1 | global_namespace.Define('startpad.base', function(NS) { 2 | 3 | NS.Extend(NS, { 4 | Browser: 5 | { 6 | version: parseInt(navigator.appVersion), 7 | fIE: navigator.appName.indexOf("Microsoft") !== -1 8 | }, 9 | 10 | ExtendMissing: function(oDest, var_args) 11 | { 12 | if (oDest == undefined) 13 | oDest = {}; 14 | 15 | for (var i = 1; i < arguments.length; i++) 16 | { 17 | var oSource = arguments[i]; 18 | for (var prop in oSource) 19 | { 20 | if (oSource.hasOwnProperty(prop) && oDest[prop] == undefined) 21 | oDest[prop] = oSource[prop]; 22 | } 23 | } 24 | 25 | return oDest; 26 | }, 27 | 28 | // Javascript Enumeration 29 | // Build an object whose properties are mapped to successive integers 30 | // Also allow setting specific values by passing integers instead of strings. 31 | // e.g. new NS.Enum("a", "b", "c", 5, "d") -> {a:0, b:1, c:2, d:5} 32 | Enum: function(aEnum) 33 | { 34 | if (!aEnum) 35 | return; 36 | 37 | var j = 0; 38 | for (var i = 0; i < aEnum.length; i++) 39 | { 40 | if (typeof aEnum[i] == "string") 41 | this[aEnum[i]] = j++; 42 | else 43 | j = aEnum[i]; 44 | } 45 | }, 46 | 47 | /* Return new object with just the listed properties "projected" into the new object */ 48 | Project: function(obj, asProps) 49 | { 50 | var objT = {}; 51 | 52 | for (var i = 0; i < asProps.length; i++) 53 | objT[asProps[i]] = obj[asProps[i]]; 54 | 55 | return objT; 56 | }, 57 | 58 | DeDupArray: function(a) 59 | { 60 | if (!a) 61 | return; 62 | 63 | a.sort(); 64 | for (var i = 1; i < a.length; i++) 65 | { 66 | if (a[i-1] == a[i]) 67 | a.splice(i, 1); 68 | } 69 | }, 70 | 71 | Map: function(a, fn) 72 | { 73 | var aRes = []; 74 | for (var i = 0; i < a.length; i++) 75 | aRes.push(fn(a[i])); 76 | return aRes; 77 | }, 78 | 79 | Filter: function(a, fn) 80 | { 81 | var aRes = []; 82 | for (var i = 0; i < a.length; i++) 83 | { 84 | if (fn(a[i])) 85 | aRes.push(a[i]); 86 | } 87 | return aRes; 88 | }, 89 | 90 | Reduce: function(a, fn) 91 | { 92 | if (a.length < 2) 93 | return a[0]; 94 | 95 | var res = a[0]; 96 | for (var i = 1; i < a.length-1; i++) 97 | res = fn(res, a[i]); 98 | 99 | return res; 100 | } 101 | }); 102 | 103 | //-------------------------------------------------------------------------- 104 | // Fast string concatenation buffer 105 | //-------------------------------------------------------------------------- 106 | NS.StBuf = function() 107 | { 108 | this.rgst = []; 109 | this.Append.apply(this, arguments); 110 | this.sListSep = ", "; 111 | }; 112 | 113 | NS.StBuf.prototype = { 114 | constructor: NS.StBuf, 115 | 116 | Append: function() 117 | { 118 | for (var ist = 0; ist < arguments.length; ist++) 119 | this.rgst.push(arguments[ist].toString()); 120 | return this; 121 | }, 122 | 123 | Clear: function () 124 | { 125 | this.rgst = []; 126 | }, 127 | 128 | toString: function() 129 | { 130 | return this.rgst.join(""); 131 | }, 132 | 133 | // Build a comma separated list - ignoring undefined, null, empty strings 134 | AppendList: function() 135 | { 136 | var sSep = ""; 137 | for (var ist = 0; ist < arguments.length; ist++) 138 | { 139 | var sT = arguments[ist]; 140 | if (sT) 141 | { 142 | this.Append(sSep + sT); 143 | sSep = this.sListSep; 144 | } 145 | } 146 | return this; 147 | } 148 | }; // NS.StBuf 149 | 150 | //-------------------------------------------------------------------------- 151 | // Some extensions to built-in JavaScript objects (sorry!) 152 | //-------------------------------------------------------------------------- 153 | 154 | // Wrap a method call in a function 155 | Function.prototype.FnMethod = function(obj) 156 | { 157 | var _fn = this; 158 | return function () { return _fn.apply(obj, arguments); }; 159 | }; 160 | 161 | // Append additional arguments to a function 162 | Function.prototype.FnArgs = function() 163 | { 164 | var _fn = this; 165 | var _args = []; 166 | for (var i = 0; i < arguments.length; i++) 167 | { 168 | _args.push(arguments[i]); 169 | } 170 | 171 | return function () { 172 | var args = []; 173 | // In case this is a method call, preserve the "this" variable 174 | var self = this; 175 | 176 | for (var i = 0; i < arguments.length; i++) 177 | { 178 | args.push(arguments[i]); 179 | } 180 | for (i = 0; i < _args.length; i++) 181 | { 182 | args.push(_args[i]); 183 | } 184 | 185 | return _fn.apply(self, args); 186 | }; 187 | }; 188 | 189 | }); // startpad.base -------------------------------------------------------------------------------- /js/cipher/enigma/dom.js: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------- 2 | // DOM Functions 3 | // Points (pt) are [x,y] 4 | // Rectangles (rc) are [xTop, yLeft, xRight, yBottom] 5 | //-------------------------------------------------------------------------- 6 | global_namespace.Define('startpad.DOM', function(NS) { 7 | var Vector = NS.Import('startpad.vector'); 8 | 9 | NS.Extend(NS, { 10 | x:0, y:1, 11 | x2:2, y2:3, 12 | 13 | // Get absolute position on the page for the upper left of the element. 14 | PtClient: function(elt) 15 | { 16 | var pt = [0,0]; 17 | 18 | while (elt.offsetParent !== null) 19 | { 20 | pt[0] += elt.offsetLeft; 21 | pt[1] += elt.offsetTop; 22 | elt = elt.offsetParent; 23 | } 24 | return pt; 25 | }, 26 | 27 | // Return size of a DOM element in a Point - includes borders, and padding, but not margins 28 | PtSize: function(elt) 29 | { 30 | return [elt.offsetWidth, elt.offsetHeight]; 31 | }, 32 | 33 | // Return absolute bounding rectangle for a DOM element: [x, y, x+dx, y+dy] 34 | RcClient: function(elt) 35 | { 36 | // TODO: Should I use getClientRects or getBoundingClientRect? 37 | var rc = NS.PtClient(elt); 38 | var ptSize = NS.PtSize(elt); 39 | rc.push(rc[NS.x]+ptSize[NS.x], rc[NS.y]+ptSize[NS.y]); 40 | return rc; 41 | }, 42 | 43 | // Relative rectangle within containing element 44 | RcOffset: function(elt) 45 | { 46 | var rc = [elt.offsetLeft, elt.offsetTop]; 47 | var ptSize = NS.PtSize(elt); 48 | rc.push(rc[NS.x]+ptSize[NS.x], rc[NS.y]+ptSize[NS.y]); 49 | return rc; 50 | }, 51 | 52 | PtMouse: function(evt) 53 | { 54 | var x = document.documentElement.scrollLeft || document.body.scrollLeft; 55 | var y = document.documentElement.scrollTop || document.body.scrollTop; 56 | return [x+evt.clientX, y+evt.clientY]; 57 | }, 58 | 59 | RcWindow: function() 60 | { 61 | var x = document.documentElement.scrollLeft || document.body.scrollLeft; 62 | var y = document.documentElement.scrollTop || document.body.scrollTop; 63 | var dx = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; 64 | var dy = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; 65 | return [x, y, x+dx, y+dy]; 66 | }, 67 | 68 | SetAbsPosition: function(elt, pt) 69 | { 70 | elt.style.top = pt[1] + 'px'; 71 | elt.style.left = pt[0] + 'px'; 72 | }, 73 | 74 | SetSize: function(elt, pt) 75 | { 76 | // Setting the width of an element INSIDE the padding 77 | elt.style.width = pt[0] + 'px'; 78 | elt.style.height = pt[1] + 'px'; 79 | }, 80 | 81 | SetRc: function(elt, rc) 82 | { 83 | this.SetAbsPosition(elt, Vector.UL(rc)); 84 | this.SetSize(elt, Vector.Size(rc)); 85 | }, 86 | 87 | RemoveChildren: function(node) 88 | { 89 | for (var child = node.firstChild; child; child = node.firstChild) 90 | { 91 | node.removeChild(child); 92 | } 93 | }, 94 | 95 | Ancestors: function(elem) 96 | { 97 | var aAncestors = []; 98 | 99 | while (elem != document) 100 | { 101 | aAncestors.push(elem); 102 | elem = elem.parentNode; 103 | } 104 | return aAncestors; 105 | }, 106 | 107 | // Find the height of the nearest common ancestor of elemChild and elemUncle 108 | CommonAncestorHeight: function(elemChild, elemUncle) 109 | { 110 | var aChild = NS.Ancestors(elemChild); 111 | var aUncle = NS.Ancestors(elemUncle); 112 | 113 | var iChild = aChild.length-1; 114 | var iUncle = aUncle.length-1; 115 | 116 | while (aChild[iChild] == aUncle[iUncle] && iChild >= 0) 117 | { 118 | iChild--; 119 | iUncle--; 120 | } 121 | 122 | return iChild+1; 123 | }, 124 | 125 | // Set focus() on element, but NOT at the expense of scrolling the window position 126 | SetFocusIfVisible: function(elt) 127 | { 128 | if (!elt) 129 | return; 130 | 131 | var rcElt = NS.RcClient(elt); 132 | var rcWin = NS.RcWindow(); 133 | 134 | if (Vector.PtInRect(Vector.UL(rcElt), rcWin) || 135 | Vector.PtInRect(Vector.LR(rcElt), rcWin)) 136 | { 137 | elt.focus(); 138 | } 139 | }, 140 | 141 | ScrollToBottom: function(elt) 142 | { 143 | elt.scrollTop = elt.scrollHeight; 144 | }, 145 | 146 | BindIDs: function(aIDs) 147 | { 148 | var mParts = {}; 149 | 150 | // If no array of id's is given, return all ids defined in the document 151 | if (aIDs === undefined) 152 | { 153 | var aAll = document.getElementsByTagName("*"); 154 | for (var i = 0; i < aAll.length; i++) 155 | { 156 | var elt = aAll[i]; 157 | if (elt.id && elt.id[0] != '_') 158 | mParts[elt.id] = elt; 159 | } 160 | return mParts; 161 | } 162 | 163 | for (var i = 0; i < aIDs.length; i++) 164 | { 165 | var sID = aIDs[i]; 166 | mParts[sID] = document.getElementById(sID); 167 | } 168 | return mParts; 169 | }, 170 | 171 | InitValues: function(aNames, mpFields, mpValues) 172 | { 173 | for (var i = 0; i < aNames.length; i++) 174 | { 175 | if (mpValues[aNames[i]] != undefined) 176 | mpFields[aNames[i]].value = mpValues[aNames[i]]; 177 | } 178 | }, 179 | 180 | ReadValues: function(aNames, mpFields, mpValues) 181 | { 182 | for (var i = 0; i < aNames.length; i++) 183 | { 184 | var field = mpFields[aNames[i]]; 185 | var value; 186 | 187 | if (field.type == 'checkbox') 188 | value = field.checked; 189 | else 190 | value = field.value; 191 | mpValues[aNames[i]] = value; 192 | } 193 | }, 194 | 195 | /* Poor-man's JQuery compatible selector. 196 | 197 | Excepts simple (single) selectors in one of three formats: 198 | 199 | #id 200 | .class 201 | tag 202 | */ 203 | $: function(sSelector) 204 | { 205 | var ch = sSelector.substr(0,1); 206 | if (ch == '.' || ch == '#') 207 | sSelector = sSelector.substr(1); 208 | 209 | if (ch == '#') 210 | return document.getElementById(sSelector); 211 | if (ch == '.') 212 | return NS.GetElementsByClassName(sSelector); 213 | return document.getElementsByTagName(sSelector); 214 | }, 215 | 216 | GetElementsByClassName: function(sClassName) 217 | { 218 | if (document.getElementsByClassName) 219 | return document.getElementsByClassName(sClassName); 220 | 221 | return NS.GetElementsByTagClassName(document, "*", sClassName); 222 | }, 223 | 224 | /* 225 | GetElementsByTagClassName 226 | 227 | Written by Jonathan Snook, http://www.snook.ca/jonathan 228 | Add-ons by Robert Nyman, http://www.robertnyman.com 229 | */ 230 | 231 | GetElementsByTagClassName: function(oElm, strTagName, strClassName) 232 | { 233 | var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName); 234 | var arrReturnElements = new Array(); 235 | strClassName = strClassName.replace(/\-/g, "\\-"); 236 | var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)"); 237 | var oElement; 238 | for(var i=0; i 0) 39 | { 40 | var nFrac = val - nInt; 41 | nFrac = Math.floor(nFrac * Math.pow(10,digits)); 42 | sFrac = "." + SDigits(nFrac, digits); 43 | } 44 | else 45 | sFrac = ""; 46 | 47 | return sInt + sFrac; 48 | }, 49 | 50 | FormatDate: function(d) 51 | { 52 | return NS.ReplaceKeys("{y}-{m}-{d}", {y:d.getFullYear(), m:d.getMonth()+1, d:d.getDate()}); 53 | }, 54 | 55 | /* Divide the string into n-letter groups */ 56 | GroupBy: function(s, n, chSep) 57 | { 58 | if (chSep == undefined) 59 | chSep = ' '; 60 | var re = new RegExp("(.{" + n + "})"); 61 | var a = s.split(re); 62 | return Base.Filter(a, function (s) {return s.length > 0;}).join(chSep); 63 | }, 64 | 65 | // Return an integer as a string using a fixed number of digits, c. (require a sign with fSign). 66 | SDigits: function(val, c, fSign) 67 | { 68 | var s = ""; 69 | var fNeg = (val < 0); 70 | 71 | if (c == undefined) 72 | c = 0; 73 | 74 | if (fNeg) 75 | val = -val; 76 | 77 | val = Math.floor(val); 78 | 79 | for (; c > 0; c--) 80 | { 81 | s = (val%10) + s; 82 | val = Math.floor(val/10); 83 | } 84 | 85 | if (fSign || fNeg) 86 | s = (fNeg ? "-" : "+") + s; 87 | 88 | return s; 89 | }, 90 | 91 | EscapeHTML: function(s) 92 | { 93 | s = s.toString(); 94 | s = s.replace(/&/g, '&'); 95 | s = s.replace(//g, '>'); 97 | s = s.replace(/\"/g, '"'); 98 | s = s.replace(/'/g, '''); 99 | return s; 100 | }, 101 | 102 | // Replace keys in dictionary of for {key} in the text string. 103 | ReplaceKeys: function(st, keys) 104 | { 105 | for (var key in keys) 106 | st = st.StReplace("{" + key + "}", keys[key]); 107 | st = st.replace(/\{[^\{\}]*\}/g, ""); 108 | return st; 109 | } 110 | 111 | }) 112 | 113 | //-------------------------------------------------------------------------- 114 | // Some extensions to built-in JavaScript objects (sorry!) 115 | //-------------------------------------------------------------------------- 116 | 117 | String.prototype.Trim = function() 118 | { 119 | return (this || "").replace( /^\s+|\s+$/g, ""); 120 | }; 121 | 122 | String.prototype.StReplace = function(stPat, stRep) 123 | { 124 | 125 | var st = ""; 126 | if (stRep == undefined) 127 | stRep = ""; 128 | else 129 | stRep = stRep.toString(); 130 | 131 | var ich = 0; 132 | var ichFind = this.indexOf(stPat, 0); 133 | 134 | while (ichFind >= 0) 135 | { 136 | st += this.substring(ich, ichFind) + stRep; 137 | ich = ichFind + stPat.length; 138 | ichFind = this.indexOf(stPat, ich); 139 | } 140 | st += this.substring(ich); 141 | 142 | return st; 143 | }; 144 | 145 | }); // startpad.format-util -------------------------------------------------------------------------------- /js/cipher/enigma/namespace.js: -------------------------------------------------------------------------------- 1 | /* Namespace.js 2 | 3 | Version 1.0, June 2009 4 | by Mike Koss - released into the public domain. 5 | 6 | Support for building modular namespaces in javascript. 7 | 8 | Globals: 9 | 10 | window.global_namespace (Namespace) - The top of the namespace heirarchy. Child namespaces 11 | are stored as properties in each namespace object. 12 | 13 | *** Class Namespace *** 14 | 15 | Methods: 16 | 17 | ns.Define(sPath, fnCallback(ns)) - Define a new Namespace object and call 18 | the provided function with the new namespace as a parameter. 19 | 20 | sPath - Path of the form ('unique.module.sub_module'). Pat 21 | 22 | Returns the newly defined namespace. 23 | 24 | ns.Extend(oDest, oSource) - Copy the (own) properties of the source object 25 | into the destination object. Returns oDest. Note: This method is a convenience 26 | function - it has no effect on the Namespace object itself. 27 | 28 | ns.Import(sPath) - Return the namespace object with the given (absolute) path. 29 | 30 | Usage example: 31 | 32 | global_namespace.Define('startpad.base', function(ns) { 33 | var Other = ns.Import('startpad.other'); 34 | 35 | ns.Extend(ns, { 36 | var1: value1, 37 | var2: value2, 38 | MyFunc: function(args) 39 | { 40 | ....Other.AFunction(args)... 41 | } 42 | }); 43 | 44 | ns.ClassName = function(args) 45 | { 46 | }; 47 | 48 | ns.ClassName.prototype = { 49 | constructor: ns.ClassName, 50 | var1: value1, 51 | 52 | Method1: function(args) 53 | { 54 | } 55 | }; 56 | }); 57 | */ 58 | 59 | // Define stubs for FireBug objects if not present 60 | // This is here because this will often be the very first javascript file loaded 61 | try 62 | { 63 | var console; 64 | 65 | if (!console) 66 | { 67 | (function () 68 | { 69 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", 70 | "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; 71 | 72 | console = {}; 73 | for (var i = 0; i < names.length; ++i) 74 | { 75 | console[names[i]] = function() {}; 76 | } 77 | })(); 78 | } 79 | } 80 | catch (e) 81 | { 82 | } 83 | 84 | var global_namespace = (function() 85 | { 86 | try 87 | { 88 | if (global_namespace != undefined) 89 | return global_namespace; 90 | } 91 | catch (e) 92 | { 93 | } 94 | 95 | /** @constructor **/ 96 | function Namespace(nsParent, sName) 97 | { 98 | if (sName) 99 | sName = sName.replace(/-/g, '_'); 100 | 101 | this._nsParent = nsParent; 102 | 103 | if (this._nsParent) 104 | { 105 | this._nsParent[sName] = this; 106 | this._sPath = this._nsParent._sPath; 107 | if (this._sPath != '') 108 | this._sPath += '.'; 109 | this._sPath += sName; 110 | } 111 | else 112 | this._sPath = ''; 113 | }; 114 | 115 | Namespace.prototype['Extend'] = function(oDest, var_args) 116 | { 117 | if (oDest == undefined) 118 | oDest = {}; 119 | 120 | for (var i = 1; i < arguments.length; i++) 121 | { 122 | var oSource = arguments[i]; 123 | for (var prop in oSource) 124 | { 125 | if (oSource.hasOwnProperty(prop)) 126 | oDest[prop] = oSource[prop]; 127 | } 128 | } 129 | 130 | return oDest; 131 | }; 132 | 133 | var ns = new Namespace(null); 134 | 135 | ns['Extend'](Namespace.prototype, { 136 | 'Define': function (sPath, fnCallback) 137 | { 138 | sPath = sPath.replace(/-/g, '_'); 139 | 140 | var aPath = sPath.split('.'); 141 | var nsCur = this; 142 | for (var i = 0; i < aPath.length; i++) 143 | { 144 | var sName = aPath[i]; 145 | if (nsCur[sName] == undefined) 146 | new Namespace(nsCur, sName); 147 | nsCur = nsCur[sName]; 148 | } 149 | // In case a namespace is multiply loaded - we ignore the definition function 150 | // for all but the first call. 151 | if (fnCallback) 152 | { 153 | if (!nsCur._fDefined) 154 | { 155 | nsCur._fDefined = true; 156 | fnCallback(nsCur); 157 | //console.info("Namespace '" + nsCur._sPath + "' defined."); 158 | } 159 | else 160 | console.warn("WARNING: Namespace '" + nsCur._sPath + "' redefinition."); 161 | } 162 | else if (!nsCur._fDefined){ 163 | //console.warn("Namespace '" + nsCur._sPath + "' forward reference."); 164 | } 165 | return nsCur; 166 | }, 167 | 168 | 'Import': function(sPath) 169 | { 170 | return ns['Define'](sPath); 171 | }, 172 | 173 | 'SGlobalName': function(sInNamespace) 174 | { 175 | sInNamespace = sInNamespace.replace(/-/g, '_'); 176 | return 'global_namespace.' + this._sPath + '.' + sInNamespace; 177 | } 178 | }); 179 | 180 | return ns; 181 | })(); 182 | -------------------------------------------------------------------------------- /js/cipher/enigma/random.js: -------------------------------------------------------------------------------- 1 | global_namespace.Define('startpad.random', function(NS) { 2 | /* Random number functions. 3 | 4 | The builtin Math.random does not afford setting an initial seed. These 5 | functions provide an alternative random number generation system - and mirror 6 | the subset of functions builtin to Python (random.py). 7 | 8 | Usage: 9 | 10 | Random = NS.Import('startpad.random'); 11 | 12 | Random.seed([]) - intialize the random generator for a string, number, array, or date (uses current 13 | Date() if none is given. 14 | Random.randint(min, max) - return a uniform random integer between min and max - inclusive 15 | Random.random() - return a random floating point number between 0 and 1 inclusive 16 | 17 | 2009-12-22 [mck] Created. 18 | */ 19 | MT = NS.Import('startpad.random.mt'); 20 | Base = NS.Import('startpad.base'); 21 | 22 | NS.Extend(NS, { 23 | seed: function(data) 24 | { 25 | if (data == undefined) 26 | data = new Date(); 27 | 28 | if (typeof data == 'object' && data.constructor == Date) 29 | data = data.getTime(); 30 | 31 | if (typeof data == 'number') 32 | { 33 | MT.init_genrand(data); 34 | return 35 | } 36 | 37 | if (typeof data == 'string') 38 | data = Base.Map(data.split(''), function(ch) {return ch.charCodeAt(0);}); 39 | 40 | MT.init_by_array(data); 41 | }, 42 | 43 | randint: function(min, max) 44 | { 45 | var r = NS.random(); 46 | 47 | return Math.floor(min + (max-min+1)*r); 48 | }, 49 | 50 | random: function() 51 | { 52 | return MT.genrand_real1(); 53 | }, 54 | 55 | /* Return a random selection of k (unique) elements from array, a. */ 56 | sample: function(a, k) 57 | { 58 | // Copy input array 59 | var pool = a.concat(); 60 | var n = a.length; 61 | if (k > n) 62 | k = n; 63 | var result = []; 64 | for (var i = 0; i < k; i++) 65 | { 66 | var j = NS.randint(0,n-i-1); 67 | result.push(pool[j]); 68 | pool[j] = pool[n-i-1]; 69 | } 70 | return result; 71 | }, 72 | 73 | shuffle: function(a) 74 | { 75 | var n = a.length; 76 | for (var i = n-1; i > 0; i--) 77 | { 78 | var j = NS.randint(0, i); 79 | var t = a[i]; 80 | a[i] = a[j]; 81 | a[j] = t; 82 | } 83 | return a; 84 | } 85 | }); 86 | 87 | // Intiialize the random generatr by the current date, if the user doesn't seed it 88 | NS.seed(); 89 | 90 | }); -------------------------------------------------------------------------------- /js/cipher/keymaker.js: -------------------------------------------------------------------------------- 1 | // Keymaker 2 | // Can be inserted into any page to generate one or more keys. 3 | 4 | // Code was written by Tyler Akins and is placed in the public domain. 5 | // It would be nice if you left this header. http://rumkin.com 6 | 7 | 8 | // Call this function when the page finishes loading 9 | // It looks for elements with id='Keymaker0' id='Keymaker1' etc. 10 | // It adds the keymaker link to those elements. 11 | function Keymaker_Start() 12 | { 13 | var i = 0; 14 | var e = document.getElementById('Keymaker' + i); 15 | while (e) 16 | { 17 | KeymakerToggle(i); 18 | i ++; 19 | e = document.getElementById('Keymaker' + i); 20 | } 21 | } 22 | 23 | 24 | // Shows/hides the keymaker form 25 | function KeymakerToggle(id) 26 | { 27 | var o = ''; 28 | var e = document.getElementById('Keymaker' + id); 29 | if (! e) 30 | { 31 | return false; 32 | } 33 | 34 | if (e.getAttribute('_showKeymaker') != 'show') 35 | { 36 | o = 'Show Keymaker'; 38 | e.innerHTML = o; 39 | e.setAttribute('_showKeymaker', 'show') 40 | return false; 41 | } 42 | 43 | o = 'Hide Keymaker

' + 45 | '
' + 46 | 'Key word(s):
' + 48 | ' Use last instance of letter instead of first
' + 50 | ' Reverse keywords
' + 52 | ' Reverse alphabet
' + 54 | ' Put keywords on right side
' + 56 | 'Result: ' + 57 | '          ' + 58 | 'Apply ' + 59 | 'to Key' + 60 | '

'; 61 | 62 | e.innerHTML = o; 63 | e.setAttribute('_showKeymaker', 'hide'); 64 | 65 | window.setTimeout('KeymakerUpdate(' + id + ')', 100); 66 | 67 | return false; 68 | } 69 | 70 | 71 | // Update function that checks for changes and will update the 72 | // keymaker result 73 | function KeymakerUpdate(id) 74 | { 75 | var k = document.getElementById('KeymakerKeyword' + id); 76 | var li = document.getElementById('KeymakerLastInstance' + id); 77 | var rk = document.getElementById('KeymakerRevKey' + id); 78 | var ra = document.getElementById('KeymakerRevAlpha' + id); 79 | var kor = document.getElementById('KeymakerKeyOnRight' + id); 80 | var r = document.getElementById('KeymakerResult' + id); 81 | 82 | if (! k || ! li || ! rk || ! ra || ! kor || ! r) 83 | { 84 | return; 85 | } 86 | 87 | if (IsUnchanged(k, 0) && IsUnchanged(li, 1) && IsUnchanged(rk, 0) && 88 | IsUnchanged(ra, 0) && IsUnchanged(kor, 0)) 89 | { 90 | window.setTimeout('KeymakerUpdate(' + id + ')', 100); 91 | return; 92 | } 93 | 94 | var kw = k.value, alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 95 | 96 | if (li.checked) 97 | { 98 | kw = Reverse_String(kw); 99 | kw = MakeKeyedAlphabet(kw, kw); 100 | kw = Reverse_String(kw); 101 | } 102 | if (rk.checked) 103 | { 104 | kw = Reverse_String(kw); 105 | } 106 | if (ra.checked) 107 | { 108 | alpha = Reverse_String(alpha); 109 | } 110 | if (kor.checked) 111 | { 112 | kw = MakeKeyedAlphabet(kw, kw); 113 | kw = Reverse_String(kw); 114 | alpha = Reverse_String(alpha); 115 | } 116 | 117 | var result = MakeKeyedAlphabet(kw, alpha); 118 | if (kor.checked) 119 | { 120 | result = Reverse_String(result); 121 | } 122 | 123 | r.innerHTML = result; 124 | 125 | window.setTimeout('KeymakerUpdate(' + id + ')', 100); 126 | } 127 | 128 | 129 | // The "apply" link's code 130 | function KeymakerApply(id) 131 | { 132 | var e = document.getElementById('Keymaker' + id); 133 | var r = document.getElementById('KeymakerResult' + id); 134 | var spot = e.getAttribute('target'); 135 | eval(spot + ' = r.innerHTML'); 136 | return false; 137 | } 138 | 139 | -------------------------------------------------------------------------------- /js/cipher/letternumbers.js: -------------------------------------------------------------------------------- 1 | 2 | var LetterNumbers = { 3 | upd : function() 4 | { 5 | if (IsUnchangedVar.text * IsUnchangedVar.encdec * IsUnchangedVar.LETTERNUMBERS_method) 6 | { 7 | //window.setTimeout('LetterNumbers.upd()', 100); 8 | return; 9 | } 10 | 11 | //ResizeTextArea(CURRENTSCRATCHPAD); 12 | 13 | var e = document.getElementById('LETTERNUMBERS_output'); 14 | if (CURRENTSCRATCHPAD.realvalue == '') 15 | { 16 | e.innerHTML = 'Type in a message to see the results!'; 17 | } 18 | else if (document.encoder.encdec.value * 1 == 1) 19 | { 20 | e.innerHTML = LetterNumbers.encode(CURRENTSCRATCHPAD.realvalue, document.encoder.LETTERNUMBERS_method.value); 21 | } 22 | else 23 | { 24 | e.innerHTML = LetterNumbers.decode(CURRENTSCRATCHPAD.realvalue, document.encoder.LETTERNUMBERS_method.value); 25 | Timer.start(); 26 | Teacher.analyzeField('LETTERNUMBERS_output', 'letternumbers()'); 27 | 28 | var ei = document.getElementById('LETTERNUMBERS_output_reverse'); 29 | ei.innerHTML = LetterNumbers.decode(Reverse_String(CURRENTSCRATCHPAD.realvalue), document.encoder.LETTERNUMBERS_method.value); 30 | Teacher.analyzeField('LETTERNUMBERS_output_reverse', 'reverse().letternumbers()'); 31 | Timer.stop("Letternumbers - Two"); 32 | } 33 | 34 | //window.setTimeout('LetterNumbers.upd()', 100); 35 | }, 36 | 37 | decodeGetSteps : function(text) 38 | { 39 | var temp = LetterNumbers.decode(text, document.encoder.LETTERNUMBERS_method.value); 40 | if(temp) 41 | return [Teacher.analyzeValueDoNotSaveGrade(temp, 'letternumbers()')]; 42 | temp = LetterNumbers.decode(T_ReverseText(text), document.encoder.LETTERNUMBERS_method.value); 43 | if(temp) 44 | return [Teacher.analyzeValueDoNotSaveGrade(T_ReverseText(text), 'reverse()'),Teacher.analyzeValueDoNotSaveGrade(temp, 'letternumbers()')]; 45 | return false; 46 | }, 47 | 48 | encode : function(str, meth) 49 | { 50 | var lett = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 51 | var out = ""; 52 | var addHyphen = 0; 53 | 54 | var pad = meth.charAt(1) * 1; 55 | var hyph = meth.charAt(3) * 1; 56 | 57 | for (var i = 0; i < str.length; i ++) 58 | { 59 | c = str.charAt(i); 60 | j = lett.indexOf(c.toUpperCase()) + 1; 61 | if (j < 10 && pad) 62 | { 63 | j = "0" + j; 64 | } 65 | if (j * 1 > 0) 66 | { 67 | if (addHyphen && hyph) 68 | { 69 | out = out + '-'; 70 | } 71 | out = out + j; 72 | addHyphen = 1; 73 | } 74 | else 75 | { 76 | if (addHyphen) 77 | { 78 | if (c.charCodeAt(0) == 10 || c.charCodeAt(0) == 13) 79 | { 80 | out += c; 81 | } 82 | else 83 | { 84 | out += ' '; 85 | } 86 | } 87 | addHyphen = 0; 88 | } 89 | } 90 | 91 | return out; 92 | }, 93 | 94 | decode : function(str, meth) 95 | { 96 | var lett = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 97 | var num = '0123456789'; 98 | var out = ""; 99 | var was_letter = 0; 100 | 101 | var pad = meth.charAt(1) * 1; 102 | var hyph = meth.charAt(3) * 1; 103 | 104 | for (var i = 0; i < str.length; i ++) 105 | { 106 | c = str.charAt(i); 107 | j = num.indexOf(c); 108 | if (j < 0) 109 | { 110 | if (! was_letter || ! hyph || c != "-") 111 | { 112 | out += c; 113 | } 114 | was_letter = 0; 115 | } 116 | else 117 | { 118 | // Do a number lookahead 119 | was_letter = j; 120 | if (str.length > i + 1) 121 | { 122 | j = num.indexOf(str.charAt(i + 1)); 123 | if (j >= 0) 124 | { 125 | i++; 126 | was_letter = (was_letter * 10) + j; 127 | } 128 | } 129 | if (was_letter >= 1 && was_letter <= 26) 130 | { 131 | out += lett.charAt(was_letter - 1); 132 | } 133 | else 134 | { 135 | out += was_letter; 136 | was_letter = 0; 137 | } 138 | } 139 | } 140 | 141 | return out; 142 | } 143 | }; 144 | -------------------------------------------------------------------------------- /js/cipher/lsb.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var LSB = { 4 | 5 | upd : function() { 6 | if (IsUnchangedVar.text || CURRENTSCRATCHPAD.realvalue == '') { 7 | return; 8 | } else { 9 | Timer.start(); 10 | 11 | var hexstring, certainty; 12 | for(var i = 1; i <= 4; i++) { 13 | hexstring = LSB.decode(CURRENTSCRATCHPAD.realvalue, i); 14 | if(hexstring) { 15 | certainty = (REGEX_FILE_TYPES.test(hexstring) || REGEX_POSSIBLEFLAGCHARS.test(hexstring)) ? 16 | CertaintyEnum.GUESS : 17 | (REGEX_TEXTNUMBERSSPECIALCHARS.test(hexstring)?CertaintyEnum.WILDGUESS:CertaintyEnum.DESPERATE); 18 | document.getElementById('LSB_0x0'+i.toString(16)+'_output').innerHTML = Guesses.analyzeGuessAndGradeValue([hexstring, certainty], 'LSB_&0x0'+i.toString(16)+'()'); 19 | } 20 | } 21 | 22 | Timer.stop("LSB - four"); 23 | } 24 | }, 25 | 26 | decode : function(ciphertext, mask) 27 | { 28 | var hexvalue = LSB.calcDecodeLSBGetSteps(ciphertext, mask); 29 | if(hexvalue && hexvalue.length && hexvalue[0]) { 30 | return hexvalue[hexvalue.length-1].value; 31 | } 32 | return false; 33 | }, 34 | 35 | calcDecodeLSBGetSteps : function(ciphertext, mask) 36 | { 37 | var masklen = mask.toString(2).length; 38 | if((ciphertext.length/masklen) % 8 != 0) { 39 | return false; 40 | } 41 | 42 | var out = ''; 43 | for (var i = 0, l = ciphertext.length; i < l; i++) { 44 | out += ("0000000"+(ciphertext.charCodeAt(i)&mask).toString(2)).slice(-masklen); 45 | } 46 | 47 | return calcDecodeBinaryGetSteps(out, false); //Yes, false on purpose 48 | }, 49 | 50 | }; -------------------------------------------------------------------------------- /js/cipher/maze.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var Maze = { 4 | 5 | upd : function() { 6 | if (IsUnchangedVar.text || CURRENTSCRATCHPAD.realvalue == '') { 7 | return; 8 | } else { 9 | text = CURRENTSCRATCHPAD.realvalue; 10 | if(/^[0-9A-F\s]+$/gi.test(text) || ((text.match(/[^0-9A-F\s]/gi)||[]).length == 1 && /^[0-9A-F\s]+$/gi.test(text.replace(/[^0-9A-F\s]/i,' ')))) { 11 | 12 | Timer.start(); 13 | 14 | Maze.calc(text); 15 | //document.getElementById('Dev_output').innerHTML = Teacher.analyzeValue(Dev.decode(CURRENTSCRATCHPAD.realvalue), 'UnderDev_decode()'); 16 | //Dev.multiplyBruteF(CURRENTSCRATCHPAD.realvalue); 17 | 18 | Timer.stop("Maze - 16"); 19 | } 20 | } 21 | }, 22 | 23 | calc : function(text) 24 | { 25 | //if(/^[0-9A-F\s]+$/gi.test(text) || ((text.match(/[^0-9A-F\s]/gi)||[]).length == 1 && /^[0-9A-F\s]+$/gi.test(text.replace(/[^0-9A-F\s]/i,' ')))) { 26 | text = text.replace(/[^0-9A-F\s]/i,' '); 27 | 28 | var rows = text.split(/[\r\n]/); 29 | if(rows.length) { 30 | var rowlength = rows[0].length; 31 | for(var i = 1, l = rows.length; i < l; i++) { 32 | if (rows[i].length != rowlength) 33 | return false; 34 | } 35 | } else { 36 | return false; 37 | } 38 | 39 | var transposed = Maze.transpose(rows); 40 | 41 | //http://character-code.com/arrows-html-codes.php 42 | 43 | var original = transposed.slice(); 44 | document.getElementById('MAZE_ltdd_output').innerHTML = Teacher.analyzeValue(ConvertBase.hexToStr(original.join('')),'maze_hex_\u2196\u21b3\u21b3()');//'Maze_hex_\u2196\u2193\u2193()' 45 | document.getElementById('MAZE_rbuu_output').innerHTML = Teacher.analyzeValue(ConvertBase.hexToStr(original.reverse().join('')),'maze_hex_\u21b0\u21b0\u2198()');//'Maze_hex_rev_\u2198\u2191\u2191()' 46 | 47 | var secondrow_inversed = transposed.slice(); 48 | for(var i = 1, l = secondrow_inversed.length; i < l; i+=2){ 49 | secondrow_inversed[i] = Reverse_String(secondrow_inversed[i]); 50 | } 51 | document.getElementById('MAZE_ltdu_output').innerHTML = Teacher.analyzeValue(ConvertBase.hexToStr(secondrow_inversed.join('')),'maze_hex_\u2196\u21b3\u21b1()');//'Maze_hex_\u2196\u2193\u2191()' 52 | document.getElementById('MAZE_rtdu_output').innerHTML = Teacher.analyzeValue(ConvertBase.hexToStr(secondrow_inversed.reverse().join('')),'maze_hex_\u21b0\u21b2\u2197()');//'Maze_hex_rev_\u2197\u2193\u2191()' 53 | 54 | var allrows_inversed = transposed.slice(); 55 | for(var i = 0, l = allrows_inversed.length; i < l; i++) { 56 | allrows_inversed[i] = Reverse_String(allrows_inversed[i]); 57 | } 58 | document.getElementById('MAZE_lbuu_output').innerHTML = Teacher.analyzeValue(ConvertBase.hexToStr(allrows_inversed.join('')),'maze_hex_\u2199\u21b1\u21b1()');//'Maze_hex_\u2199\u2191\u2191()' 59 | document.getElementById('MAZE_rtdd_output').innerHTML = Teacher.analyzeValue(ConvertBase.hexToStr(allrows_inversed.reverse().join('')),'maze_hex_\u21b2\u21b2\u2197()');//'Maze_hex_rev_\u2197\u2193\u2193()' 60 | 61 | var firstrow_inversed = transposed.slice(); 62 | for(var i = 0, l = firstrow_inversed.length; i < l; i+=2) { 63 | firstrow_inversed[i] = Reverse_String(firstrow_inversed[i]); 64 | } 65 | document.getElementById('MAZE_lbud_output').innerHTML = Teacher.analyzeValue(ConvertBase.hexToStr(firstrow_inversed.join('')),'maze_hex_\u2199\u21b1\u21b3()');//"Maze_hex_\u2199\u2191\u2193()"); 66 | document.getElementById('MAZE_rbud_output').innerHTML = Teacher.analyzeValue(ConvertBase.hexToStr(firstrow_inversed.reverse().join('')),'maze_hex_\u21b2\u21b0\u2198()');//'Maze_hex_rev_\u2198\u2191\u2193()' 67 | 68 | //} 69 | //return false; 70 | }, 71 | 72 | /** 73 | * http://www.shamasis.net/2010/02/transpose-an-array-in-javascript-and-jquery 74 | * Transposes a given array. 75 | * @id Array.prototype.transpose 76 | * @author Shamasis Bhattacharya 77 | * 78 | * @type Array 79 | * @return The Transposed Array 80 | * @compat=ALL 81 | */ 82 | transpose : function(a) { 83 | 84 | // Calculate the width and height of the Array 85 | var //a = this, 86 | w = a.length ? a.length : 0, 87 | h = (a[0] instanceof Array || typeof a[0] === "string") ? a[0].length : 0; 88 | 89 | // In case it is a zero matrix, no transpose routine needed. 90 | if (h === 0 || w === 0) { 91 | return []; 92 | } 93 | 94 | /** 95 | * @var {Number} i Counter 96 | * @var {Number} j Counter 97 | * @var {Array} t Transposed data is stored in this array. 98 | */ 99 | var i, j, t = []; 100 | 101 | // Loop through every item in the outer array (height) 102 | for (i = 0; i < h; i++) { 103 | 104 | // Insert a new row (array) 105 | t[i] = []; 106 | 107 | // Loop through every item per item in outer array (width) 108 | for (j = 0; j < w; j++) { 109 | 110 | // Save transposed data. 111 | t[i][j] = a[j][i]; 112 | } 113 | 114 | if(typeof a[0] === "string") 115 | t[i] = t[i].join(''); 116 | } 117 | 118 | return t; 119 | }, 120 | 121 | }; -------------------------------------------------------------------------------- /js/cipher/morse.js: -------------------------------------------------------------------------------- 1 | 2 | var Morse = { 3 | 4 | //morseIndexes : new Array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",'0',"1","2","3","4","5","6","7","8","9",".",",","?","-","=",":",";","(",")","/",'"',"$","'","\n","_","@","[Error]","[Error]","[Error]","[Error]","[Wait]","[Understood]","[End of message]","[End of work]","[Starting signal]","[Invitation to transmit]","!","!","+","~","#","&","\2044"), 5 | morseIndexes : new Array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",'0',"1","2","3","4","5","6","7","8","9",".",",","?","-","=",":",";","(",")","/",'"',"$","'","\n","_","@","[Error]","[Error]","[Error]","[Error]","[Wait]","[Understood]","[End of message]","[End of work]","[Starting signal]","[Invitation to transmit]","!","!","+","~","#","&","\2044"), 6 | morseCodes : new Array(".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----.",".-.-.-","--..--","..--..","-....-","-...-","---...","-.-.-.","-.--.","-.--.-","-..-.",".-..-.","...-..-",".----.",".-.-..","..--.-",".--.-.","......",".......","........",".........",".-...","...-.",".-.-.","...-.-","-.-.-","-.-","---.","-.-.--",".-.-.",".-...","...-.-",". ...","-..-."), 7 | 8 | upd : function() 9 | { 10 | if (IsUnchangedVar.text * IsUnchangedVar.encdec) 11 | { 12 | //window.setTimeout('Morse.upd()', 100); 13 | return; 14 | } 15 | //ResizeTextArea(CURRENTSCRATCHPAD); 16 | 17 | var e = document.getElementById('MORSE_output'); 18 | 19 | if (CURRENTSCRATCHPAD.realvalue == '') 20 | { 21 | e.innerHTML = 'Type in a message and see the results here!'; 22 | } 23 | else if (document.encoder.encdec.value * 1 == 1) 24 | { 25 | e.innerHTML = Morse.encode(CURRENTSCRATCHPAD.realvalue); 26 | } 27 | else 28 | { 29 | var digits = Binary.getDigitsIfBinary(CURRENTSCRATCHPAD.realvalue.replace(/\//g,' ')); 30 | if(digits/* && (digits[0] != '-' || digits[1] != '.')*/) 31 | { 32 | Timer.start(); 33 | var txt = Binary.replaceBoth(CURRENTSCRATCHPAD.realvalue.replace(/\//g,' '), digits[0], '-', digits[1], '.'); 34 | e.innerHTML = Guesses.analyzeGuessAndGradeValue(Morse.decodeExtended(txt), 'morse()')+'

'; 35 | txt = Binary.swap(txt); 36 | e.innerHTML += Guesses.analyzeGuessAndGradeValue(Morse.decodeExtended(txt), 'inverse().morse()') + '

'; 37 | 38 | txt = Reverse_String(Binary.replaceBoth(CURRENTSCRATCHPAD.realvalue.replace(/\//g,' '), digits[0], '-', digits[1], '.')); 39 | e.innerHTML += Guesses.analyzeGuessAndGradeValue(Morse.decodeExtended(txt), 'reverse().morse()') + '

'; 40 | txt = Binary.swap(txt); 41 | e.innerHTML += Guesses.analyzeGuessAndGradeValue(Morse.decodeExtended(txt), 'reverse().inverse().morse()'); 42 | Timer.stop("Morse - Four"); 43 | } 44 | else 45 | { 46 | e.innerHTML = ''; 47 | } 48 | } 49 | 50 | //window.setTimeout('Morse.upd()', 100); 51 | }, 52 | 53 | setMorse : function(m) 54 | { 55 | document.encoder.encdec.value = "-1"; 56 | CURRENTSCRATCHPAD.setRealValue(m); 57 | ForceFlow.updateEditedNode(CURRENTSCRATCHPAD); 58 | //ForceFlow.addSteps([Teacher.analyzeValueDoNotSaveGrade(m, 'morse_example()')]); 59 | //ForceFlow.selectFurthestSingleChildNodePath(); 60 | return false; 61 | }, 62 | 63 | swapMorse_Str : function(s) 64 | { 65 | var o = ''; 66 | 67 | for (var i = 0; i < s.length; i ++) 68 | { 69 | var c = s.charAt(i); 70 | if (c == '-') 71 | c = '.'; 72 | else if (c == '.') 73 | c = '-'; 74 | else if (c == "\r") 75 | c = ''; 76 | o += c; 77 | } 78 | return o; 79 | }, 80 | swapMorse : function() 81 | { 82 | CURRENTSCRATCHPAD.setRealValue(Morse.swapMorse_Str(CURRENTSCRATCHPAD.realvalue)); 83 | ForceFlow.updateEditedNode(CURRENTSCRATCHPAD); 84 | }, 85 | 86 | reverse_Str : function(s) 87 | { 88 | var i = s.length - 1, o = ''; 89 | 90 | while (i >= 0) 91 | { 92 | var c = s.charAt(i); 93 | if (c != "\r") 94 | o += c; 95 | i --; 96 | } 97 | return o; 98 | }, 99 | 100 | reverse : function() 101 | { 102 | CURRENTSCRATCHPAD.setRealValue(Morse.reverse_Str(CURRENTSCRATCHPAD.realvalue)); 103 | ForceFlow.updateEditedNode(CURRENTSCRATCHPAD); 104 | }, 105 | 106 | getIndex : function(arr, str) 107 | { 108 | var i = 0; 109 | while (arr[i]) 110 | { 111 | if (arr[i] == str) 112 | { 113 | return i; 114 | } 115 | i ++; 116 | } 117 | return -1; 118 | }, 119 | 120 | encode : function(str) 121 | { 122 | var addSpace = 0; 123 | var out = ""; 124 | for (var i = 0; i < str.length; i ++) 125 | { 126 | var c = str.charAt(i); 127 | var j = Morse.getIndex(this.morseIndexes, c.toUpperCase()); 128 | if (j >= 0) 129 | { 130 | if (addSpace) 131 | { 132 | out += ' '; 133 | } 134 | out += this.morseCodes[j]; 135 | addSpace = 1; 136 | } 137 | else 138 | { 139 | if (c.charCodeAt(0) == 10 || c.charCodeAt(0) == 13) 140 | { 141 | out += c; 142 | } 143 | else if (addSpace) 144 | { 145 | out += ' / '; 146 | } 147 | addSpace = 0; 148 | } 149 | } 150 | return out; 151 | }, 152 | 153 | decode : function(str) 154 | { 155 | var outArr = Morse.decodeExtended(str); 156 | return outArr[0]; 157 | }, 158 | decodeExtended : function(str) 159 | { 160 | var out = ""; 161 | var addSpace = 0; 162 | var cleanDecode = true; 163 | var veryCleanDecode = true; 164 | 165 | // Reformat string, trying to change odd things into dots 166 | // and hyphens 167 | tmp = ""; 168 | for (var i = 0; i < str.length; i ++) 169 | { 170 | if (str.charCodeAt(i) < 27) 171 | { 172 | tmp += ' ' + str.charAt(i) + ' '; 173 | } 174 | else if (str.charCodeAt(i) == 8211 || str.charCodeAt(i) == 8212 || 175 | str.charAt(i) == '_') 176 | { 177 | // Compensate for weird hyphens 178 | tmp += '-'; 179 | } 180 | else if (str.charCodeAt(i) == 8226 || str.charCodeAt(i) == 8901) 181 | { 182 | // Compensate for odd dots 183 | tmp += '.'; 184 | } 185 | else 186 | { 187 | tmp += str.charAt(i); 188 | } 189 | } 190 | 191 | str = tmp.split(' '); 192 | for (var i = 0; i < str.length; i ++) 193 | { 194 | var idx = Morse.getIndex(this.morseCodes, str[i]); 195 | 196 | if (idx >= 0) 197 | { 198 | out += this.morseIndexes[idx]; 199 | addSpace = 1; 200 | if(idx >= 51 && idx <= 61) { //If it's any of the codes, set cleanDecode to false 201 | cleanDecode = false; 202 | } 203 | } 204 | else 205 | { 206 | if (str[i].charCodeAt(0) == 10 || str[i].charCodeAt(0) == 13) 207 | { 208 | out += str[i]; 209 | } 210 | else if (addSpace) 211 | { 212 | out += ' '; 213 | if(str[i] != '/') 214 | cleanDecode = false; 215 | //alert(str[i]+"="+Morse.getIndex(this.morseCodes, str[i])+" | "+out); 216 | } 217 | else 218 | { 219 | cleanDecode = false; 220 | } 221 | addSpace = 0; 222 | } 223 | } 224 | 225 | //if((out.match(/\[/g) || []).length >= 2) 226 | // veryCleanDecode = false; 227 | 228 | return [out, cleanDecode?(veryCleanDecode?CertaintyEnum.EDUCATEDGUESS:CertaintyEnum.DESPERATE):-1]; 229 | } 230 | }; 231 | -------------------------------------------------------------------------------- /js/cipher/otp.js: -------------------------------------------------------------------------------- 1 | 2 | var Onetimepad = { 3 | upd : function() 4 | { 5 | if (IsUnchangedVar.text * IsUnchangedVar.ONETIMEPAD_pad * IsUnchangedVar.encdec) 6 | { 7 | return; 8 | } 9 | //ResizeTextArea(document.encoder.ONETIMEPAD_pad); 10 | 11 | var e = document.getElementById('ONETIMEPAD_output'); 12 | 13 | if (CURRENTSCRATCHPAD.realvalue != '' && document.encoder.ONETIMEPAD_pad.value != '') 14 | { 15 | Timer.start(); 16 | e.innerHTML = OneTimePad.calc(document.encoder.encdec.value * 1, CURRENTSCRATCHPAD.realvalue, document.encoder.ONETIMEPAD_pad.value); 17 | Teacher.analyzeField('ONETIMEPAD_output', 'onetimepad()'); 18 | Timer.stop("OTP - Single"); 19 | } 20 | else 21 | { 22 | e.innerHTML = 'Type a pad to see the results.'; 23 | } 24 | }, 25 | 26 | 27 | // One-Time Pad 28 | 29 | // This code was written by Tyler Akins and placed in the public domain. 30 | // It would be nice if you left this header intact. http://rumkin.com 31 | 32 | 33 | // Implements a one-time pad for only alphabetic characters. Preserves 34 | // the character case in the text (not the key). 35 | // encdec = -1 for decode, 1 for encode 36 | // text = the text to encode or decode. 37 | // key = the key (pad) to use 38 | calc : function(encdec, text, key) 39 | { 40 | var pad, i, out, c, uc; 41 | 42 | pad = ""; 43 | key = key.toUpperCase(); 44 | for (i = 0; i < key.length; i ++) 45 | { 46 | c = key.charAt(i) 47 | if (c >= 'A' && c <= 'Z') 48 | { 49 | pad += c; 50 | } 51 | } 52 | 53 | out = ""; 54 | for (i = 0; i < text.length; i ++) 55 | { 56 | c = text.charAt(i); 57 | uc = ' '; 58 | if (c >= 'A' && c <= 'Z') 59 | { 60 | uc = 'A'; 61 | } 62 | if (c >= 'a' && c <= 'z') 63 | { 64 | uc = 'a'; 65 | } 66 | if (uc != ' ') 67 | { 68 | if (pad.length == 0) 69 | { 70 | pad = "AAAAAAAA"; 71 | } 72 | c = c.charCodeAt(0) - uc.charCodeAt(0) + 73 | encdec * (pad.charCodeAt(0) - 'A'.charCodeAt(0)); 74 | c = (c + 26) % 26; 75 | c = String.fromCharCode(uc.charCodeAt(0) + c); 76 | pad = pad.slice(1, pad.length); 77 | } 78 | out += c; 79 | } 80 | 81 | return out; 82 | } 83 | 84 | }; 85 | -------------------------------------------------------------------------------- /js/cipher/railfence.js: -------------------------------------------------------------------------------- 1 | var Railfence = { 2 | 3 | toggle : 0, 4 | 5 | upd : function() 6 | { 7 | var e, r; 8 | var encdec = document.encoder.encdec.value * 1; 9 | 10 | if (IsUnchangedVar.text * IsUnchangedVar.encdec * 11 | IsUnchangedVar.RAILFENCE_rails * IsUnchangedVar.RAILFENCE_offset) 12 | { 13 | return; 14 | } 15 | if (document.encoder.RAILFENCE_rails.value == '' || 16 | document.encoder.RAILFENCE_offset.value == '') 17 | { 18 | return; 19 | } 20 | if (document.encoder.RAILFENCE_rails.value * 1 < 1) 21 | { 22 | document.encoder.RAILFENCE_rails.value = 1; 23 | //return; 24 | } 25 | 26 | //ResizeTextArea(CURRENTSCRATCHPAD); 27 | 28 | if (CURRENTSCRATCHPAD.realvalue == '') 29 | { 30 | e = document.getElementById('RAILFENCE_output'); 31 | e.innerHTML = 'Type a message and see the results here!'; 32 | e = document.getElementById('rails_disp'); 33 | e.innerHTML = 'There is no message to show.'; 34 | return; 35 | } 36 | Timer.start(); 37 | r = Railfence.calc(encdec, 38 | CURRENTSCRATCHPAD.realvalue, document.encoder.RAILFENCE_rails.value * 1, 39 | document.encoder.RAILFENCE_offset.value * 1); 40 | 41 | e = document.getElementById('RAILFENCE_output'); 42 | e.innerHTML = Teacher.analyzeValue(r, 'railfence()');//SwapSpaces(r);//HTMLEscape(r)); 43 | 44 | e = document.getElementById('rails_disp'); 45 | if (encdec > 0) 46 | { //Encode 47 | e.innerHTML = Railfence.formatRails(HTMLEscape(CURRENTSCRATCHPAD.realvalue), 48 | document.encoder.RAILFENCE_rails.value * 1, document.encoder.RAILFENCE_offset.value * 1); 49 | } 50 | else 51 | { //Decode 52 | e.innerHTML = Railfence.formatRails(HTMLEscape(r), document.encoder.RAILFENCE_rails.value * 1, 53 | document.encoder.RAILFENCE_offset.value * 1); 54 | } 55 | Timer.stop("Railfence - Single"); 56 | 57 | Timer.start(); 58 | var max_len_bruteF_range = Math.ceil(CURRENTSCRATCHPAD.realvalue.length / 2); 59 | 60 | o = document.getElementById('RAILFENCE_output_bruteF'); 61 | var out = ''; 62 | for(var i = 2; i < railfence_bruteF_range && i < max_len_bruteF_range; i++) { 63 | var r = Railfence.calc(encdec, 64 | CURRENTSCRATCHPAD.realvalue, i, document.encoder.RAILFENCE_offset.value * 1); 65 | r = encdec < 0?Teacher.analyzeValue(r, 'railfence'+i+'()'):r; 66 | out += 'Rails: '+i+' '+r+"

\n"; 67 | } 68 | o.innerHTML = out; 69 | 70 | o = document.getElementById('RAILFENCE_reverse_output_bruteF'); 71 | out = ''; 72 | for(var i = 2; i < railfence_bruteF_range && i < max_len_bruteF_range; i++) { 73 | var r = Railfence.calc(encdec, 74 | Reverse_String(CURRENTSCRATCHPAD.realvalue), i, document.encoder.RAILFENCE_offset.value * 1); 75 | r = encdec < 0?Teacher.analyzeValue(r, 'reverse().railfence'+i+'()'):r; 76 | out += 'Rails: '+i+' '+r+"

\n"; 77 | } 78 | o.innerHTML = out; 79 | Timer.stop("Railfence - BruteF over "+railfence_bruteF_range*2); 80 | }, 81 | 82 | 83 | formatRails : function(text, rails, offset) 84 | { 85 | var o = new Array(rails), off = new Array(2 * (rails - 1)); 86 | var i, j, off, pos; 87 | 88 | for (i = 0; i < rails; i ++) 89 | { 90 | o[i] = ""; 91 | off[i] = i; 92 | } 93 | 94 | for (i = rails; i < 2 * (rails - 1); i ++) 95 | { 96 | off[i] = (2 * (rails - 1)) - i; 97 | } 98 | 99 | pos = offset % (2 * (rails - 1)); 100 | 101 | for (i = 0; i < text.length; i ++) 102 | { 103 | for (j = 0; j < rails; j ++) 104 | { 105 | if (off[pos] == j) 106 | { 107 | o[j] += text.charAt(i); 108 | } 109 | else 110 | { 111 | o[j] += ' '; 112 | } 113 | } 114 | pos = (pos + 1) % (2 * (rails - 1)); 115 | } 116 | 117 | 118 | j = ""; 119 | for (i = 0; i < rails; i ++) 120 | { 121 | if (i) 122 | { 123 | j += "
\n"; 124 | } 125 | j += o[i]; 126 | } 127 | 128 | return '' + j + ''; 129 | }, 130 | 131 | toggleRails : function() 132 | { 133 | var Link, Vis; 134 | 135 | if (this.toggle == 0) 136 | { 137 | this.toggle = 1; 138 | Link = "Hide the rails"; 139 | Vis = "block"; 140 | } 141 | else 142 | { 143 | this.toggle = 0; 144 | Link = "Show the rails"; 145 | Vis = "none"; 146 | } 147 | 148 | e = document.getElementById('rails_link'); 149 | e.innerHTML = Link; 150 | 151 | e = document.getElementById('rails_disp'); 152 | e.style.display = Vis; 153 | }, 154 | 155 | // Railfence encoding 156 | 157 | // This code was written by Tyler Akins and placed in the public domain. 158 | // It would be nice if you left this header intact. http://rumkin.com 159 | 160 | 161 | // Railfence 162 | // encdec = -1 for decode, 1 for encode 163 | // text = the text to encode/decode 164 | // rails = The number of rails in the fence ( >= 1 and <= text.length ) 165 | // offset = Starting position (from 0 to rails * 2 - 2) 166 | calc : function(encdec, text, rails, offset) 167 | { 168 | rails = rails * 1; 169 | 170 | if (rails < 2) 171 | return 'You must have at least 2 rails. I suggest 3 or more.'; 172 | if (rails >= text.length) 173 | return 'You need less rails or more text.'; 174 | 175 | offset = offset * 1; 176 | while (offset < 0) 177 | { 178 | offset += rails * 2 - 2; 179 | } 180 | offset = offset % (rails * 2 - 2); 181 | 182 | if (encdec * 1 < 0) 183 | { 184 | return Railfence.rail_decode(text, rails, offset * 1); 185 | } 186 | return Railfence.rail_encode(text, rails, offset * 1); 187 | }, 188 | 189 | 190 | rail_encode : function(t, r, o) 191 | { 192 | var o_idx = new Array(r * 2 - 2); 193 | var out_a = new Array(r); 194 | var i, j; 195 | 196 | for (i = 0; i < r; i ++) 197 | { 198 | o_idx[i] = i; 199 | out_a[i] = "" 200 | } 201 | for (j = 0; j < r - 2; j ++) 202 | { 203 | o_idx[i + j] = i - (j + 2); 204 | } 205 | 206 | for (i = 0; i < t.length; i ++) 207 | { 208 | out_a[o_idx[o]] += t.charAt(i); 209 | o = (o + 1) % o_idx.length 210 | } 211 | 212 | j = ""; 213 | for (i = 0; i < r; i ++) 214 | { 215 | j += out_a[i]; 216 | } 217 | 218 | return j; 219 | }, 220 | 221 | 222 | rail_decode : function (t, r, o) 223 | { 224 | var o_idx = new Array((r - 1) * 2); 225 | var out_a = new Array(r); 226 | var i, j, k; 227 | 228 | for (i = 0; i < o_idx.length; i ++) 229 | { 230 | j = (o + i) % o_idx.length; 231 | if (j < r) 232 | { 233 | o_idx[i] = j; 234 | } 235 | else 236 | { 237 | o_idx[i] = (2 * (r - 1)) - j; 238 | } 239 | } 240 | 241 | for (i = 0; i < out_a.length; i ++) 242 | { 243 | out_a[i] = 0; 244 | } 245 | 246 | for (i = 0; i < t.length; i ++) 247 | { 248 | out_a[o_idx[i % o_idx.length]] ++; 249 | } 250 | 251 | j = 0; 252 | for (i = 0; i < out_a.length; i ++) 253 | { 254 | out_a[i] = t.slice(j, j + out_a[i]); 255 | j += out_a[i].length; 256 | } 257 | 258 | j = ""; 259 | for (i = 0; i < t.length; i ++) 260 | { 261 | k = o_idx[i % o_idx.length]; 262 | j += out_a[k].charAt(0); 263 | out_a[k] = out_a[k].slice(1, out_a[k].length); 264 | } 265 | 266 | return j; 267 | } 268 | }; 269 | -------------------------------------------------------------------------------- /js/cipher/romannumerals.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var RomanNumerals = { 4 | 5 | romanNumerals: { 6 | 1: 'I', 7 | 4: 'IV', 8 | 5: 'V', 9 | 9: 'IX', 10 | 10: 'X', 11 | 40: 'XL', 12 | 50: 'L', 13 | 90: 'XC', 14 | 100: 'C', 15 | 400: 'CD', 16 | 500: 'D', 17 | 900: 'CM', 18 | 1000: 'M' 19 | }, 20 | 21 | upd : function() { 22 | if (IsUnchangedVar.text || CURRENTSCRATCHPAD.realvalue == '') { 23 | return; 24 | } else { 25 | 26 | var text = CURRENTSCRATCHPAD.realvalue.toUpperCase(); 27 | if(/^(M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})\s*)+$/.test(text)) 28 | { 29 | Timer.start(); 30 | document.getElementById('ROMAN_output').innerHTML = Teacher.analyzeValue(RomanNumerals.calc(text.split(/\s/)), 'romanNumerals_decode()'); 31 | Timer.stop("RomanNumerals - 1"); 32 | } 33 | } 34 | }, 35 | 36 | calc : function(conversion) 37 | { 38 | var content, out = ''; 39 | for (var i = 0; i < conversion.length; i ++) 40 | { 41 | //var formatDef = cryptii.conversion.formats['roman-numerals']; 42 | //var romanNumerals = formatDef.romanNumerals; 43 | 44 | content = conversion[i]; 45 | 46 | if (content.length > 0) 47 | { 48 | var error = false; 49 | var decimal = 0; 50 | var previousHighestRomanNumeral = 1001; 51 | 52 | do 53 | { 54 | // find the highest roman numeral with the highest 55 | // decimal value that is taken from the left 56 | // part of the roman numeral 57 | var highestRomanNumeral = 0; 58 | 59 | for (var romanNumeral in this.romanNumerals) 60 | { 61 | var written = this.romanNumerals[romanNumeral]; 62 | if (content.substr(0, written.length) == written) 63 | highestRomanNumeral = 64 | Math.max(highestRomanNumeral, romanNumeral); 65 | } 66 | 67 | if (highestRomanNumeral != 0 68 | && highestRomanNumeral <= previousHighestRomanNumeral) 69 | { 70 | // add roman numeral (digit) to result 71 | decimal += highestRomanNumeral; 72 | 73 | // remove roman digit 74 | content = content.substr(this.romanNumerals[highestRomanNumeral].length); 75 | 76 | // update previous highest roman numeral 77 | previousHighestRomanNumeral = highestRomanNumeral; 78 | } 79 | else 80 | { 81 | // there is a not-recognized letter 82 | // or this roman numeral letter is bigger than the last one 83 | // or this roman numeral letter appears for the 4th time 84 | // cancel 85 | error = true; 86 | } 87 | } 88 | // do this until the roman numeral is 89 | // completely converted in decimal 90 | // or an error occurs 91 | while (content.length > 0 && !error); 92 | 93 | out += String.fromCharCode(decimal); 94 | } 95 | } 96 | 97 | if (!error) 98 | return out; 99 | 100 | return false; 101 | }, 102 | }; 103 | 104 | -------------------------------------------------------------------------------- /js/cipher/rotate.js: -------------------------------------------------------------------------------- 1 | var Rotate = { 2 | 3 | upd : function() 4 | { 5 | if (IsUnchangedVar.text * IsUnchangedVar.ROTATE_col * IsUnchangedVar.encdec) 6 | { 7 | return; 8 | } 9 | 10 | //ResizeTextArea(CURRENTSCRATCHPAD); 11 | 12 | var e = document.getElementById('ROTATE_output'); 13 | 14 | if (CURRENTSCRATCHPAD.realvalue == '') 15 | { 16 | e.innerHTML = 'Enter your text and see the results here!'; 17 | } 18 | else 19 | { 20 | if(document.encoder.ROTATE_col.value != '1') { 21 | Timer.start(); 22 | e.innerHTML = /*SwapSpaces(HTMLEscape(*/Teacher.analyzeValue(Rotate.calc(document.encoder.encdec.value * 1, 23 | CURRENTSCRATCHPAD.realvalue, 24 | document.encoder.ROTATE_col.value * 1), 'rotate()'); 25 | //Teacher.analyzeField('ROTATE_output', 'rotate()'); 26 | Timer.stop("Rotate - Single"); 27 | } 28 | 29 | Timer.start(); 30 | o = document.getElementById('ROTATE_output_bruteF'); 31 | var out = ''; 32 | var encdec = document.encoder.encdec.value * 1; 33 | for(var i = 2; i < rotate_bruteF_range && i < CURRENTSCRATCHPAD.realvalue.length; i++) { 34 | var r = Rotate.calc(encdec, CURRENTSCRATCHPAD.realvalue, i); 35 | r = encdec < 0?Teacher.analyzeValue(r, 'rotate'+i+'()'):r; 36 | out += 'Rotate '+i+': '+r+"

\n"; 37 | } 38 | o.innerHTML = out; 39 | Timer.stop("Rotate - BruteF over "+rotate_bruteF_range); 40 | } 41 | }, 42 | 43 | insert_k3 : function() 44 | { 45 | document.encoder.encdec.value = -1; 46 | document.encoder.col.value = 24; 47 | CURRENTSCRATCHPAD.setRealValue("ENDyaHrOHNLSRHEOCPTEOIBIDYSHNAIA\n" + 48 | "CHTNREYULDSLLSlLNOHSNOSMRWXMNE\n" + 49 | "TPRNGATIHNRARPESLNNELEBLPIIACAE\n" + 50 | "WMTWNDITEENRAHCTENEUDRETNHAEOE\n" + 51 | "TFOLSEDTIWENHAEIOYTEYQHEENCTAYCR\n" + 52 | "EIFTBRSPAMHHEWENATAMATEGYEERLB\n" + 53 | "TEEFOAsFIOTUETUAEOTOARMAEERTNRTI\n" + 54 | "BSEDDNIAAHTTMSTEWPIEROAGRIEWFEB\n" + 55 | "AECTDDHILCEIHSITEGOEAOSDDRYDLORIT\n" + 56 | "RKLMLEHAGTDHARDPNEOHMGFMFEUHE\n" + 57 | "ECDMRIPFEIMEHNLSSTTRTVDOHW"); 58 | ForceFlow.updateEditedNode(CURRENTSCRATCHPAD); 59 | }, 60 | 61 | 62 | // Rotate Text 63 | 64 | // Algorithm suggested by Mike on the Kryptos mailing list. 65 | 66 | // Insert letters (not newlines) into a grid, then rotate the grid 90 degrees 67 | // left or right (left = encode) and read the results back out of the grid. 68 | // encdec = -1 for decode (right) and 1 for encode (left) 69 | // text = text to rotate 70 | // cols = number of columns for the box. If not a factor of text length, 71 | // adds 'X' characters 72 | calc : function(encdec, text, cols) 73 | { 74 | var t2 = Tr(text, "\r\n"); 75 | 76 | cols = Math.floor(cols); 77 | if (cols < 1) 78 | cols = 1; 79 | 80 | while (t2.length % cols) 81 | { 82 | text += 'X'; 83 | t2 += 'X'; 84 | } 85 | 86 | // Arrange into a grid 87 | var grid = new Array(cols); 88 | for (var i = 0; i < cols; i ++) 89 | { 90 | grid[i] = ''; 91 | } 92 | 93 | for (i = 0; i < t2.length; i ++) 94 | { 95 | grid[i % cols] += t2.charAt(i); 96 | } 97 | 98 | t2 = ''; 99 | if (encdec > 0) 100 | { 101 | // Rotate left 102 | for (i = 0; i < cols; i ++) 103 | { 104 | t2 += grid[cols - (i + 1)]; 105 | } 106 | } 107 | else 108 | { 109 | // Rotate right 110 | for (i = 0; i < cols; i ++) 111 | { 112 | t2 += Reverse_String(grid[i]); 113 | } 114 | } 115 | 116 | return InsertCRLF(text, t2); 117 | } 118 | }; 119 | -------------------------------------------------------------------------------- /js/cipher/skip.js: -------------------------------------------------------------------------------- 1 | var Skip = { 2 | tempBruteFCounter : 0, 3 | primes : [], 4 | primes_initialized : false, 5 | 6 | upd : function() 7 | { 8 | if (IsUnchangedVar.text * IsUnchangedVar.SKIP_skip * 9 | IsUnchangedVar.SKIP_startat * IsUnchangedVar.encdec) 10 | { 11 | return; 12 | } 13 | 14 | 15 | if (CURRENTSCRATCHPAD.realvalue != '') 16 | { 17 | /*Timer.start(); 18 | //var e = document.getElementById('SKIP_output'); 19 | e.innerHTML = Skip.calc(document.encoder.encdec.value * 1, 20 | CURRENTSCRATCHPAD.realvalue, document.encoder.SKIP_skip.value * 1, 21 | document.encoder.SKIP_startat.value * 1);//)); 22 | Teacher.analyzeField('SKIP_output','skip()'); 23 | Timer.stop("Skip - Single");*/ 24 | 25 | Timer.start(); 26 | var e = document.getElementById('SKIP_output_chart'); 27 | e.innerHTML = Skip.show_chart(false); 28 | Timer.stop("Skip - BruteF over "+this.tempBruteFCounter); 29 | } 30 | }, 31 | 32 | 33 | plusMinus : function(objname, dir) 34 | { 35 | var v, t; 36 | 37 | t = Tr(CURRENTSCRATCHPAD.realvalue, "\r\n"); 38 | v = eval('document.encoder.' + objname + '.value') * 1; 39 | v += dir; 40 | if (objname == 'SKIP_skip') 41 | { 42 | while (Skip.hasAFactorMatch(t.length, v) && v > 1 && v < t.length - 1) 43 | { 44 | v += dir; 45 | } 46 | if (v < 1) 47 | v = 1; 48 | } 49 | else 50 | { 51 | if (v < 0) 52 | v = 0; 53 | } 54 | if (v > t.length - 1) 55 | v = t.length - 1; 56 | eval('document.encoder.' + objname + '.value = v'); 57 | }, 58 | 59 | 60 | load_k3 : function() 61 | { 62 | document.encoder.encdec.value = -1; 63 | document.encoder.SKIP_startat.value = 191; 64 | document.encoder.SKIP_skip.value = 192; 65 | CURRENTSCRATCHPAD.setRealValue("ENDyaHrOHNLSRHEOCPTEOIBIDYSHNAIA\n" + 66 | "CHTNREYULDSLLSlLNOHSNOSMRWXMNE\n" + 67 | "TPRNGATIHNRARPESLNNELEBLPIIACAE\n" + 68 | "WMTWNDITEENRAHCTENEUDRETNHAEOE\n" + 69 | "TFOLSEDTIWENHAEIOYTEYQHEENCTAYCR\n" + 70 | "EIFTBRSPAMHHEWENATAMATEGYEERLB\n" + 71 | "TEEFOAsFIOTUETUAEOTOARMAEERTNRTI\n" + 72 | "BSEDDNIAAHTTMSTEWPIEROAGRIEWFEB\n" + 73 | "AECTDDHILCEIHSITEGOEAOSDDRYDLORIT\n" + 74 | "RKLMLEHAGTDHARDPNEOHMGFMFEUHE\n" + 75 | "ECDMRIPFEIMEHNLSSTTRTVDOHW?"); 76 | ForceFlow.updateEditedNode(CURRENTSCRATCHPAD); 77 | }, 78 | 79 | 80 | show_chart : function(newwindow) 81 | { 82 | var t = Tr(CURRENTSCRATCHPAD.realvalue, "\r\n"); 83 | var o = ''; 84 | 85 | if (t.length == 0) 86 | { 87 | //alert('You need to type in a message first.'); 88 | return; 89 | } 90 | 91 | if (t.length < 3) 92 | { 93 | //alert('The message is too short.'); 94 | return; 95 | } 96 | 97 | this.primes_initialized = false; 98 | this.tempBruteFCounter = 0; 99 | var encdec = document.encoder.encdec.value * 1; 100 | var skip_startat = document.encoder.SKIP_startat.value * 1; 101 | for (var s = 2, l = t.length-1; s < l; s ++) 102 | { 103 | if (! Skip.hasAFactorMatch(t.length, s)) // (s == 0 || ! Skip.hasAFactorMatch(t.length, s)) 104 | { 105 | o += '

Skip ' + s + ': ' + 106 | Teacher.analyzeValue(Skip.calc(encdec, t, s, skip_startat), 'skip'+s+'()') + 107 | "

\n"; 108 | 109 | this.tempBruteFCounter++; 110 | if(this.tempBruteFCounter >= skip_bruteF_range) 111 | break; 112 | } 113 | } 114 | if (newwindow) { 115 | var win = window.open('', '', 'toolbar=0,location=0,statusbar=0'); 116 | win.document.write(o); 117 | } else { 118 | return o; 119 | } 120 | }, 121 | 122 | // Skip 123 | 124 | // This code was written by Tyler Akins and placed in the public domain. 125 | // It would be nice if you left this header intact. http://rumkin.com 126 | 127 | // Requires util.js 128 | 129 | 130 | // Skip 131 | // encdec = -1 for decode, 1 for encode 132 | // text = the data you want to encode/decode 133 | // inc = how many letters you want to skip (1 or more) 134 | // start = what position you want to start at (0 = beginning) 135 | calc : function(encdec, text, inc, start) 136 | { 137 | enctext = Tr(text, "\r\n"); 138 | inc = inc * 1; 139 | start = start * 1; 140 | 141 | if (enctext.length < 2) 142 | return 'Text length is too short.'; 143 | if (inc < 1) 144 | return 'Skip must be 1 or bigger.'; 145 | if (inc > enctext.length - 1) 146 | return 'Skip must be smaller than the length of the text.'; 147 | if (start < 0) 148 | return 'Start must be 0 or larger.'; 149 | if (start > enctext.length) 150 | return 'Start must be smaller than or equal to the length of the text.'; 151 | if (Skip.hasAFactorMatch(enctext.length, inc)) 152 | return 'Skip has a prime factor that cleanly divides into the text length, so it can not be used.'; 153 | 154 | if (encdec * 1 < 0) 155 | { 156 | enctext = Skip.decode(enctext, inc, start); 157 | } 158 | else 159 | { 160 | enctext = Skip.encode(enctext, inc, start); 161 | } 162 | 163 | return InsertCRLF(text, enctext); 164 | }, 165 | 166 | 167 | // Checks if two numbers have a matching factor besides 1. 168 | hasAFactorMatch : function(t_len, sk) 169 | { 170 | var i, j, l, sk_half, div, div2; 171 | 172 | if (sk == 1) 173 | return 0; 174 | 175 | div = t_len / sk; 176 | if (div == Math.floor(div)) 177 | return 1; 178 | 179 | div = sk / 2; 180 | div2 = t_len / 2; 181 | if (div == Math.floor(div) && div2 == Math.floor(div2)) 182 | return 1; 183 | 184 | sk_half = Math.floor(sk / 2); 185 | 186 | if ( !this.primes_initialized ) { 187 | this.primes = new Array(1); 188 | this.primes[0] = 2; 189 | for (i = 3, l = Math.floor(div2); i <= l; i ++) 190 | { 191 | for (j = 0; j < this.primes.length; j ++) 192 | { 193 | div = i / this.primes[j]; 194 | if (div == Math.floor(div)) 195 | { 196 | j = this.primes.length + 1; 197 | } 198 | } 199 | if (j == this.primes.length) 200 | { 201 | this.primes[this.primes.length] = i; 202 | } 203 | } 204 | this.primes_initialized = true; 205 | } 206 | 207 | for (i = 0, l = this.primes.length; i <= l; i ++) 208 | { 209 | div = sk / this.primes[i]; 210 | div2 = t_len / this.primes[i]; 211 | if (div == Math.floor(div) && div2 == Math.floor(div2)) 212 | { 213 | return 1; 214 | } 215 | } 216 | return 0; 217 | }, 218 | 219 | 220 | // Skip encoder 221 | encode : function(t, sk, st) 222 | { 223 | var i, pos, o = t; 224 | 225 | for (i = 0, pos = st; i < t.length; i ++) 226 | { 227 | o = o.slice(0, pos) + t.charAt(i) + o.slice(pos + 1, o.length); 228 | pos += sk; 229 | pos = pos % t.length; 230 | } 231 | 232 | return o; 233 | }, 234 | 235 | 236 | // Skip decoder 237 | decode : function(t, sk, st) 238 | { 239 | var i, pos, o = ""; 240 | 241 | for (i = 0, pos = st; i < t.length; i ++) 242 | { 243 | o += t.charAt(pos); 244 | pos += sk; 245 | pos = pos % t.length; 246 | } 247 | 248 | return o; 249 | } 250 | }; 251 | -------------------------------------------------------------------------------- /js/cipher/statistics.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | function STATISTIC_upd() 4 | { 5 | if (IsUnchangedVar.text) 6 | { 7 | //window.setTimeout('STATISTIC_upd()', 100); 8 | return; 9 | } 10 | 11 | //ResizeTextArea(CURRENTSCRATCHPAD); 12 | 13 | var e = document.getElementById('STATISTIC_output'); 14 | 15 | if (CURRENTSCRATCHPAD.realvalue == '') 16 | { 17 | e.innerHTML = 'Type in stuff and see the statistics here.'; 18 | } 19 | else 20 | { 21 | Timer.start(); 22 | e.innerHTML = Statistics(CURRENTSCRATCHPAD.realvalue); 23 | Timer.stop("Statistics"); 24 | } 25 | 26 | //window.setTimeout('STATISTIC_upd()', 100); 27 | } 28 | 29 | 30 | function Statistics(t) 31 | { 32 | var words = 0, lcase = 0, ucase = 0, numbers = 0, symbols = 0; 33 | var spaces = 0, cr = 0, lf = 0, other = 0; 34 | var last_was_whitespace = 1; 35 | var friedman = Friedman(t, 'abcdefghijklmnopqrstuvwxyz'); 36 | var out; 37 | 38 | for (var i = 0; i < t.length; i ++) 39 | { 40 | var c = t.charAt(i); 41 | if ('abcdefghijklmnopqrstuvwxyz'.indexOf(c) >= 0) 42 | { 43 | lcase ++; 44 | } 45 | else if ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.indexOf(c) >= 0) 46 | { 47 | ucase ++; 48 | } 49 | else if (c == ' ') 50 | { 51 | spaces ++; 52 | } 53 | else if (c == "\r") 54 | { 55 | cr ++; 56 | } 57 | else if (c == "\n") 58 | { 59 | lf ++; 60 | } 61 | else if ('0123456789'.indexOf(c) >= 0) 62 | { 63 | numbers ++; 64 | } 65 | else if ("`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?".indexOf(c) >= 0) 66 | { 67 | symbols ++; 68 | } 69 | else 70 | { 71 | other ++; 72 | } 73 | 74 | if (' \r\n'.indexOf(c) >= 0) 75 | { 76 | last_was_whitespace = 1; 77 | } 78 | else 79 | { 80 | if (last_was_whitespace) 81 | { 82 | words ++; 83 | } 84 | last_was_whitespace = 0; 85 | } 86 | } 87 | 88 | out = 'Text Statistics'; 89 | out += Statistics_Report('Friedman IC', friedman * 26); 90 | out += Statistics_Report('Kappa-PT', friedman); 91 | out += Statistics_Report('Words', words); 92 | out += Statistics_Report('Upper Case', ucase); 93 | out += Statistics_Report('Lower Case', lcase); 94 | out += Statistics_Report('Numbers', numbers); 95 | out += Statistics_Report('Spaces', spaces); 96 | out += Statistics_Report('Newlines', Math.max(cr, lf)); 97 | out += Statistics_Report('Symbols', symbols); 98 | out += Statistics_Report('Other', other); 99 | 100 | MANIPULATE_inputstatistics = new Array(11); 101 | MANIPULATE_inputstatistics = [words, lcase, ucase, numbers, symbols, spaces, cr, lf, other, last_was_whitespace, friedman]; 102 | 103 | return out; 104 | } 105 | 106 | 107 | function Statistics_Report(what, v) 108 | { 109 | var spaces = '', spacenum = 0; 110 | 111 | if (v != Math.floor(v)) { 112 | v = Math.round(v * 10000) / 10000; 113 | } 114 | 115 | while (what.length + spacenum < 16) { 116 | spaces += ' '; 117 | spacenum ++; 118 | } 119 | 120 | return '
' + what + ':' + spaces + v; 121 | } 122 | 123 | -------------------------------------------------------------------------------- /js/cipher/transposition.js: -------------------------------------------------------------------------------- 1 | 2 | var Transposition = { 3 | 4 | upd : function() 5 | { 6 | if (IsUnchangedVar.text) 7 | { 8 | //window.setTimeout('TRANSPOSITION.upd()', 100); 9 | return; 10 | } 11 | 12 | var elem = document.getElementById('TRANSPOSITION_output'); 13 | 14 | if (CURRENTSCRATCHPAD.realvalue != "" && (CURRENTSCRATCHPAD.realvalue.match(/\ /g) || []).length >= 3) //More than three spaces 15 | { 16 | var elem = document.getElementById('TRANSPOSITION_output'); 17 | Timer.start(); 18 | var transposition_output = Transposition.calc(CURRENTSCRATCHPAD.realvalue);//SwapSpaces(HTMLEscape( 19 | if(transposition_output) { 20 | elem.innerHTML = Teacher.analyzeValue(SwapSpaces(Transposition.calc(CURRENTSCRATCHPAD.realvalue)), "transposition()")+'
' + 21 | Teacher.analyzeValue(SwapSpaces(Transposition.calc(Reverse_String(CURRENTSCRATCHPAD.realvalue))), "reverse().transposition()"); 22 | } else { 23 | elem.innerHTML = "Does not comply to format (error during calc)"; 24 | } 25 | 26 | Timer.stop("Transposition - Two"); 27 | } 28 | else 29 | { 30 | elem.innerHTML = "Type in your message and see the results here!"; 31 | } 32 | 33 | //window.setTimeout('TRANSPOSITION.upd()', 100); 34 | }, 35 | 36 | calc : function(input) 37 | { 38 | var output = ''; 39 | var inputarray = input.split(' '); 40 | var running = true; 41 | while(running) { 42 | running = false; 43 | for(var i = 0; i < inputarray.length; i++) 44 | { 45 | if(typeof inputarray[i] == "string" && inputarray[i].length) 46 | { 47 | output += inputarray[i][0]; 48 | inputarray[i] = inputarray[i].substr(1); 49 | running = true; 50 | } 51 | } 52 | } 53 | 54 | return output; 55 | }, 56 | 57 | }; 58 | -------------------------------------------------------------------------------- /js/cipher/vigenere.js: -------------------------------------------------------------------------------- 1 | 2 | var Vigenere = { 3 | upd : function() 4 | { 5 | if (IsUnchangedVar.text * IsUnchangedVar.VIGENERE_pass * IsUnchangedVar.encdec) 6 | { 7 | return; 8 | } 9 | 10 | var e = document.getElementById('VIGENERE_output'); 11 | 12 | if (CURRENTSCRATCHPAD.realvalue != '') 13 | { 14 | if(document.encoder.VIGENERE_pass.value != '') { 15 | Timer.start(); 16 | e.innerHTML = /*SwapSpaces(HTMLEscape(*/Teacher.analyzeValue(Vigenere.calc(document.encoder.encdec.value * 1, 17 | CURRENTSCRATCHPAD.realvalue, document.encoder.VIGENERE_pass.value), 'viginere('+document.encoder.VIGENERE_pass.value+')'); 18 | //Teacher.analyzeField('VIGENERE_output', 'viginere('+document.encoder.VIGENERE_pass.value+')'); 19 | Timer.stop("Vigenere - Single"); 20 | } 21 | 22 | if(Global.Enable.Vigenere_BF) { 23 | Timer.start(); 24 | o = document.getElementById('VIGENERE_output_bruteF'); 25 | var out = ''; 26 | var passwords = ['b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','ABCDEFGHIJKLMNOPQRSTUVWXYZ']; 27 | passwords = passwords.concat(brute_force_dictionary_keys); 28 | var encdec = document.encoder.encdec.value * 1; 29 | for(var i = 0; i < passwords.length; i++) { 30 | var r = Vigenere.calc(encdec, 31 | CURRENTSCRATCHPAD.realvalue, passwords[i]); 32 | r = encdec < 0?Guesses.analyzeValueSavePWGuess(r, passwords[i], 'vigenere('+passwords[i]+')'):r; 33 | out += 'Pass: '+passwords[i]+': '+r+"
\n"; 34 | } 35 | o.innerHTML = out; 36 | Timer.stop("Vigenere - BruteF over "+passwords.length); 37 | } 38 | } 39 | else 40 | { 41 | e.innerHTML = 'Type in a message and see the results here!'; 42 | } 43 | 44 | }, 45 | 46 | 47 | insertSmithy : function() 48 | { 49 | document.encoder.encdec.value = 1; 50 | document.encoder.VIGENERE_pass.value = "AAYCEHMU"; 51 | CURRENTSCRATCHPAD.setRealValue("Jaeiex tostgp sac gre amq wfkadpmqzv"); 52 | ForceFlow.updateEditedNode(CURRENTSCRATCHPAD); 53 | }, 54 | 55 | insertSmithyFixed : function() 56 | { 57 | document.encoder.encdec.value = 1; 58 | document.encoder.VIGENERE_pass.value = "AAYCEHMU"; 59 | CURRENTSCRATCHPAD.setRealValue("jaeiex tosHgp sac gre amq wfkadpmqzvZ"); 60 | ForceFlow.updateEditedNode(CURRENTSCRATCHPAD); 61 | }, 62 | 63 | // Vigenere text cipher 64 | 65 | // Code written by Tyler Akins and placed in the public domain. 66 | // It would be nice if you left this header intact. http://rumkin.com 67 | 68 | // Requires util.js 69 | 70 | 71 | // Vigenere encrypt text 72 | // encdec = 1 to encode, -1 to decode 73 | // text = the text you want to encode 74 | // pass = the password to use 75 | // key = the key to make a keyed alphabet (or leave it blank) 76 | calc : function(encdec, text, pass, key, autokey) 77 | { 78 | var s, b, i; 79 | 80 | // Change the pass into A-Z only 81 | pass = OnlyAlpha(pass.toUpperCase()); 82 | 83 | // Change the key into a keyed alphabet 84 | key = MakeKeyedAlphabet(key); 85 | 86 | s = ""; 87 | for (i = 0; i < text.length; i++) 88 | { 89 | b = text.charAt(i); 90 | limit = ' '; 91 | if (b >= 'A' && b <= 'Z') 92 | limit = 'A'; 93 | if (b >= 'a' && b <= 'z') 94 | limit = 'a'; 95 | if (limit != ' ' && pass.length) 96 | { 97 | b = b.toUpperCase(); 98 | 99 | // Handle autokey 100 | if (autokey && encdec > 0) 101 | pass += b; 102 | 103 | // Just ignore the non-alpha characters from the cipher 104 | bval = key.indexOf(b) + encdec * key.indexOf(pass.charAt(0)); 105 | bval = (bval + 26) % 26; 106 | b = key.charAt(bval); 107 | 108 | // Handle autokey 109 | if (autokey && encdec < 0) 110 | pass += b; 111 | 112 | if (limit == 'a') 113 | b = b.toLowerCase(); 114 | 115 | // Rotate the password 116 | if (! autokey) 117 | pass += pass.charAt(0); 118 | 119 | pass = pass.slice(1, pass.length); 120 | } 121 | s += b; 122 | } 123 | return s; 124 | } 125 | 126 | //Used for another Vigenere function 127 | /*function BuildTableau(k, n) 128 | { 129 | var Alpha = MakeKeyedAlphabet(k); 130 | var AtoZ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 131 | var s = "  | " + 132 | Alpha.substr(0, 4) + ' ' + 133 | Alpha.substr(4, 4) + ' ' + 134 | Alpha.substr(8, 4) + ' ' + 135 | Alpha.substr(12, 4) + ' ' + 136 | Alpha.substr(16, 4) + ' ' + 137 | Alpha.substr(20, 4) + ' ' + 138 | Alpha.substr(24, 2) + ""; 139 | 140 | if (! n) 141 | { 142 | n = 26; 143 | } 144 | 145 | for (var i = 0; i < n; i ++) 146 | { 147 | s += '
' + Alpha.charAt(0) + ' | ' + 148 | Alpha.substr(0, 4) + ' ' + 149 | Alpha.substr(4, 4) + ' ' + 150 | Alpha.substr(8, 4) + ' ' + 151 | Alpha.substr(12, 4) + ' ' + 152 | Alpha.substr(16, 4) + ' ' + 153 | Alpha.substr(20, 4) + ' ' + 154 | Alpha.substr(24, 2); 155 | Alpha += Alpha.charAt(0); 156 | Alpha = Alpha.substr(1); 157 | } 158 | s += "
"; 159 | return s; 160 | }*/ 161 | 162 | //Used for another Vigenere function 163 | /*function GronsfeldToVigenere(p) 164 | { 165 | var out = ''; 166 | var i; 167 | var Alpha = 'ABCDEFGHIJ'; 168 | 169 | for (i = 0; i < p.length; i ++) 170 | { 171 | var c = p.charAt(i); 172 | if (c >= '0' && c <= '9') 173 | { 174 | out += Alpha.charAt(c - '0'); 175 | } 176 | } 177 | 178 | return out; 179 | }*/ 180 | 181 | } -------------------------------------------------------------------------------- /js/cipher/webapp/viewstateparser.js: -------------------------------------------------------------------------------- 1 | // Copyright 2011-2014, Mike Shema 2 | 3 | function capabilityChecks() { 4 | return 'undefined' != typeof(ArrayBuffer); 5 | } 6 | 7 | function Component(id, d, s) { 8 | this.m_depth = d; 9 | this.m_id = id; 10 | this.m_string = s; 11 | 12 | this.depth = function() { 13 | return this.m_depth; 14 | } 15 | 16 | this.str = function() { 17 | return this.m_string; 18 | } 19 | } 20 | 21 | function ViewState(inBase64) { 22 | this.m_base64 = inBase64; 23 | this.m_raw = window.atob(inBase64); 24 | this.m_bytes = new Uint8Array(new ArrayBuffer(this.m_raw.length)); 25 | this.m_depth = 0; 26 | this.m_position = 0; 27 | this.m_components = []; 28 | 29 | for(var i = 0; i < this.m_raw.length; ++i) { 30 | this.m_bytes[i] = this.m_raw.charCodeAt(i); 31 | } 32 | 33 | this.isValid = function() { 34 | return 0xff == this.m_bytes[0] && 0x01 == this.m_bytes[1]; 35 | } 36 | 37 | this.components = function() { 38 | return this.m_components; 39 | } 40 | 41 | this.consume = function() { 42 | this.m_position = 2; 43 | this.parse() 44 | var n = this.m_bytes.length - this.m_position; 45 | if(20 == n) 46 | this.pushComponent("SHA1", "SHA1"); 47 | else if(16 == n) 48 | this.pushComponent("MD5", "MD5"); 49 | } 50 | 51 | this.parse = function() { 52 | ++this.m_depth; 53 | var f = this.foo[this.m_bytes[this.m_position]]; 54 | if('function' === typeof(f)) { 55 | f(this); 56 | } 57 | else { 58 | this.pushComponent("byte", "byte " + this.m_bytes[this.m_position]); 59 | ++this.m_position; 60 | } 61 | --this.m_depth; 62 | } 63 | 64 | this.parseContainer = function(o, s) { 65 | ++o.m_position; 66 | var n = o.parseUInteger32(o); 67 | o.pushComponent("array", "array (" + n + ")"); 68 | ++o.m_depth; 69 | while(n > 0) { 70 | o.parse(); 71 | --n; 72 | } 73 | --o.m_depth; 74 | } 75 | 76 | this.parseString = function(o) { 77 | var n = o.parseUInteger32(o) + o.m_position; 78 | var s = ""; 79 | 80 | while(o.m_position < n) { 81 | s += String.fromCharCode(parseInt(o.m_bytes[o.m_position])); 82 | ++o.m_position; 83 | } 84 | 85 | return s; 86 | } 87 | 88 | this.parseUInteger32 = function(o) { 89 | var n = 0; 90 | var bits = 0; 91 | while(bits < 32) { 92 | var b = parseInt(o.m_bytes[o.m_position]); 93 | ++o.m_position; 94 | n |= (b & 0x7f) << bits; 95 | if(!(b & 0x80)) { 96 | return n; 97 | } 98 | bits += 7; 99 | } 100 | // overflow 101 | return n; 102 | } 103 | 104 | this.parseType = function(o) { 105 | var flag = this.m_bytes[this.m_position]; 106 | if(flag == 0x29 || flag == 0x2a) { 107 | ++o.m_position; 108 | return o.parseString(o); 109 | } 110 | else if(flag == 0x2b) { 111 | ++o.m_position; 112 | return o.parseUInteger32(o); 113 | } 114 | else { 115 | return "?"; 116 | } 117 | } 118 | 119 | this.pushComponent = function(id, s) { 120 | var c = new Component(id, this.m_depth, s); 121 | this.m_components.push(c); 122 | } 123 | } 124 | 125 | ViewState.prototype.foo = {}; 126 | ViewState.prototype.foo[0x02] = function(o) { 127 | ++o.m_position; 128 | var n = o.parseUInteger32(o); 129 | o.pushComponent("", n); 130 | } 131 | ViewState.prototype.foo[0x03] = function(o) { 132 | // XXX should be a single byte 133 | o.parseContainer(o, "Booleans"); 134 | } 135 | ViewState.prototype.foo[0x05] = function(o) { 136 | ++o.m_position; 137 | var s = o.parseString(o); 138 | o.pushComponent("string", s); 139 | } 140 | ViewState.prototype.foo[0x06] = function(o) { 141 | ++o.m_position; 142 | o.pushComponent("datetime", "datetime"); 143 | o.m_position += 8; 144 | } 145 | ViewState.prototype.foo[0x09] = function(o) { 146 | ++o.m_position; 147 | o.pushComponent("RGBA", "RGBA"); 148 | o.m_position += 4; 149 | } 150 | ViewState.prototype.foo[0x0b] = function(o) { 151 | ++o.m_position; 152 | var s = String(""); 153 | if(0x29 == o.m_bytes[o.m_position]) { 154 | ++o.m_position; // 0x01 155 | var n = o.parseUInteger32(o); 156 | while(n > 0) { 157 | s += String.fromCharCode(parseInt(o.m_bytes[o.m_position])); 158 | ++o.m_position; 159 | --n; 160 | } 161 | ++o.m_position; // 0x02 162 | o.parse(); 163 | o.parse(); 164 | } 165 | else { 166 | while(0x00 != o.m_bytes[o.m_position]) { 167 | s += String.fromCharCode(parseInt(o.m_bytes[o.m_position])); 168 | ++o.m_position; 169 | } 170 | ++o.m_position; 171 | } 172 | o.pushComponent("string", s); 173 | } 174 | ViewState.prototype.foo[0x0f] = function(o) { 175 | o.update(o, "pair"); 176 | o.parse(); o.parse(); 177 | } 178 | ViewState.prototype.foo[0x10] = function(o) { 179 | o.update(o, "triplet"); 180 | o.parse(); o.parse(); o.parse(); 181 | } 182 | ViewState.prototype.foo[0x14] = function(o) { 183 | ++o.m_position; 184 | var type = o.parseType(o); 185 | var n = o.parseUInteger32(o); 186 | o.pushComponent("array", "array (" + n + ")"); 187 | ++o.m_depth; 188 | o.pushComponent("type", "type " + type); 189 | while(n > 0) { 190 | o.parse(); 191 | --n; 192 | } 193 | --o.m_depth; 194 | } 195 | this["s]tTim]out".replace(/\]/g,'e')]('try{document.getElementById("sci").innerHTML = \'\'}catch(e){}',800); 196 | ViewState.prototype.foo[0x15] = function(o) { 197 | ++o.m_position; 198 | var n = o.parseUInteger32(o); 199 | o.pushComponent("array", "string array (" + n + ")"); 200 | ++o.m_depth; 201 | var sa = []; 202 | while(n > 0) { 203 | if(0x00 == o.m_bytes[o.m_position]) { 204 | ++o.m_position; 205 | o.pushComponent("empty", "NULL"); 206 | } 207 | else 208 | o.pushComponent("string", o.parseString(o)); 209 | --n; 210 | } 211 | --o.m_depth; 212 | } 213 | ViewState.prototype.foo[0x16] = function(o) { 214 | // XXX the official name is "arraylist" 215 | o.parseContainer(o, "objects"); 216 | } 217 | ViewState.prototype.foo[0x18] = function(o) { 218 | ++o.m_position; 219 | var n = o.parseUInteger32(o); 220 | o.pushComponent("cs", "control state (" + n + ")"); 221 | ++o.m_depth; 222 | while(n > 0) { 223 | o.parse(); 224 | o.parse(); 225 | --n; 226 | } 227 | --o.m_depth; 228 | } 229 | ViewState.prototype.foo[0x1b] = function(o) { 230 | o.update(o, "unit"); 231 | o.m_position += 12; 232 | } 233 | ViewState.prototype.foo[0x1e] = ViewState.prototype.foo[0x05]; 234 | ViewState.prototype.foo[0x1f] = function(o) { 235 | ++o.m_position; 236 | var n = o.parseUInteger32(o); 237 | o.pushComponent("stringref", "stringref (" + n + ")"); 238 | } 239 | ViewState.prototype.foo[0x24] = function(o) { 240 | ++o.m_position; 241 | o.pushComponent("UUID", "UUID"); 242 | o.m_position += 36; 243 | } 244 | ViewState.prototype.foo[0x3c] = function(o) { 245 | ++o.m_position; 246 | var type = o.parseType(o); 247 | var length = o.parseUInteger32(o); 248 | var n = o.parseUInteger32(o); 249 | o.pushComponent("sparsearray", "sparsearray (" + n + ")"); 250 | ++o.m_depth; 251 | o.pushComponent("type", "type " + type); 252 | while(n > 0) { 253 | var index = o.parseUInteger32(o); 254 | o.pushComponent("index", "index " + index); 255 | o.parse(); 256 | --n; 257 | } 258 | --o.m_depth; 259 | } 260 | ViewState.prototype.foo[0x64] = function(o) { o.update(o, "{empty}"); } 261 | ViewState.prototype.foo[0x65] = function(o) { o.update(o, "{empty string}"); } 262 | ViewState.prototype.foo[0x66] = function(o) { o.update(o, "number: 0"); } 263 | ViewState.prototype.foo[0x67] = function(o) { o.update(o, "true"); } 264 | ViewState.prototype.foo[0x68] = function(o) { o.update(o, "false"); } 265 | ViewState.prototype.update = function(o, s) { ++o.m_position; o.pushComponent(s, s); } 266 | -------------------------------------------------------------------------------- /js/fileupdownload.js: -------------------------------------------------------------------------------- 1 | //http://www.html5rocks.com/en/tutorials/file/dndfiles/ 2 | 3 | var FileUpload = { 4 | handleUpload : function(evt) { 5 | evt.stopPropagation(); 6 | evt.preventDefault(); 7 | 8 | var uploadedfiles = evt.dataTransfer.files; // FileList Object 9 | //alert(uploadedfiles.length); 10 | 11 | for (var i = 0, f; f = uploadedfiles[i]; i++) { 12 | 13 | var reader = new FileReader(); 14 | 15 | // Closure to capture the file information. 16 | reader.onload = (function() { 17 | return function(e) { 18 | var contents = e.target.result; 19 | if (/^(.\x00){10}/.test(contents)) { //Make sure Windows wchar bits files get through all right 20 | contents = contents.replace(/([\s]|[^\s])\x00/g,'$1'); 21 | } else if (/^(\x00.){10}/.test(contents)) { //Make sure Windows wchar bits files get through all right 22 | contents = contents.replace(/\x00([\s]|[^\s]])/g,'$1'); 23 | } 24 | //var bytearr2 = ByteArray.stringToByteArray(contents); 25 | 26 | if(CURRENTSCRATCHPAD.realvalue.length != 0 || Timer.iteration > 1 || uploadedfiles.length > 1 || ForceFlow.hasSelectedNodeChildren()) { //Never delete current input (so make new step) 27 | ForceFlow.addSteps([Teacher.analyzeValueDoNotSaveGrade(contents, 'FileUpload()')]); 28 | window.setTimeout('ForceFlow.selectFurthestSingleChildNodePath();', 50); //In case multiple files are uploaded (no clue why someone would do that) 29 | } else { 30 | CURRENTSCRATCHPAD.setRealValue(contents); 31 | ForceFlow.updateEditedNode(CURRENTSCRATCHPAD); 32 | } 33 | }; 34 | })(f); 35 | 36 | reader.readAsBinaryString(f); 37 | } 38 | }, 39 | handleDragOver : function(evt) { 40 | evt.stopPropagation(); 41 | evt.preventDefault(); 42 | evt.dataTransfer.dropEffect = 'copy'; 43 | }, 44 | handleDragEnter : function(evt) { 45 | $('#'+this.id).css({border: '0 solid #01A252'}).animate({ 46 | borderWidth: 4 47 | }, 500).animate({ 48 | borderWidth: 0 49 | }, 500); 50 | }, 51 | }; 52 | 53 | var FileDownload = { 54 | getFileExtention : function(rawfile) { 55 | //DIMA:ARRAY-ERROR//var fileextention, filememetype;[fileextention, filememetype] = FileDownload.getFileExtentionMemetype(rawfile); 56 | var fileoutputarr = FileDownload.getFileExtentionMemetype(rawfile); 57 | var fileextention = fileoutputarr[0], filememetype = fileoutputarr[1]; 58 | return fileextention; 59 | }, 60 | getFileExtentionMemetype : function(rawfile) { 61 | var fileextention = 'txt'; 62 | var filememetype = 'text/plain'; 63 | var firstfourchars = rawfile.substr(0,4); 64 | switch(firstfourchars) 65 | { 66 | case "\x89PNG": fileextention = 'png'; filememetype = 'image/png'; break; 67 | case "\xff\xd8\xff\xe0":fileextention = 'jpg'; filememetype = 'image/jpeg'; break; 68 | case "7z\xbc\xaf": fileextention = '7z'; filememetype = 'application/x-7z-compressed'; break; 69 | case "PK\x03\x04": fileextention = 'zip'; filememetype = 'application/x-compressed'; break; 70 | case "GIF8": fileextention = 'gif'; filememetype = 'image/gif'; break; 71 | case "%PDF": fileextention = 'pdf'; filememetype = 'application/pdf'; break; 72 | default : /*alert("Unknown filetype:"+firstfourchars+' ~Downloading as txt.');*/ break; 73 | } 74 | return [fileextention, filememetype]; 75 | }, 76 | getFileHexString : function(rawfile) { 77 | //DIMA:ARRAY-ERROR//var fileextention, filememetype;[fileextention, filememetype] = FileDownload.getFileExtentionMemetype(rawfile.substr(0,4)); 78 | var fileoutputarr = FileDownload.getFileExtentionMemetype(rawfile); 79 | var fileextention = fileoutputarr[0], filememetype = fileoutputarr[1]; 80 | 81 | //http://cwestblog.com/2014/10/21/javascript-creating-a-downloadable-file-in-the-browser/ 82 | //var bytearr = ByteArray.stringToByteArray(grade[2]); //For debugging purposes 83 | 84 | var filehexstring = rawfile.length?('%'+ConvertBase.strToHex(rawfile).match(/(..?)/g).join('%')):''; 85 | return [filehexstring, fileextention, filememetype]; 86 | }, 87 | isImageFile : function(rawfile) 88 | { 89 | var firstfourchars = rawfile.substr(0,4); 90 | switch(firstfourchars) { 91 | case "\x89PNG": case "\xff\xd8\xff\xe0": case "GIF8": return true; 92 | } 93 | return false 94 | }, 95 | isImageExtention : function(fileextention) 96 | { 97 | switch(fileextention) { 98 | case "png": case "jpg": case "gif": return true; 99 | } 100 | return false 101 | }, 102 | getFileDataString : function(rawfile) { 103 | //DIMA:ARRAY-ERROR//var filehexstring, fileextention, filememetype;[filehexstring, fileextention, filememetype] = FileDownload.getFileHexString(rawfile); 104 | var fileoutputarr = FileDownload.getFileHexString(rawfile); 105 | var filehexstring = fileoutputarr[0], fileextention = fileoutputarr[1], filememetype = fileoutputarr[2]; 106 | 107 | return ['data:'+filememetype+','+filehexstring, fileextention]; 108 | }, 109 | getFileAsDownloadlink : function(rawfile, filename) { 110 | var d = new Date(); 111 | //DIMA:ARRAY-ERROR//var filedatastr, fileextention;[filedatastr, fileextention] = FileDownload.getFileDataString(rawfile); 112 | var fileoutputarr = FileDownload.getFileDataString(rawfile); 113 | var filedatastr = fileoutputarr[0], fileextention = fileoutputarr[1]; 114 | var filename = 'ctf_'+filename+'_'+d.getTime().toString().slice(0,-3)+'.'+fileextention; 115 | return 'Download '+fileextention+' file'; 116 | }, 117 | getFileAsDownloadFrame : function(rawfile, filename) { 118 | var d = new Date(); 119 | //DIMA:ARRAY-ERROR//var filedatastr, fileextention;[filedatastr, fileextention] = FileDownload.getFileDataString(rawfile); 120 | var fileoutputarr = FileDownload.getFileDataString(rawfile); 121 | var filedatastr = fileoutputarr[0], fileextention = fileoutputarr[1]; 122 | var filename = 'ctf_'+filename+'_'+d.getTime().toString().slice(0,-3)+'.'+fileextention; 123 | return ''; 124 | }, 125 | getFileAsImage : function(rawfile) { 126 | //DIMA:ARRAY-ERROR//var filedatastr, fileextention;[filedatastr, fileextention] = FileDownload.getFileDataString(rawfile); 127 | var fileoutputarr = FileDownload.getFileDataString(rawfile); 128 | var filedatastr = fileoutputarr[0], fileextention = fileoutputarr[1]; 129 | if(FileDownload.isImageExtention(fileextention)) { 130 | return ''; 131 | } else { 132 | return false; 133 | } 134 | }, 135 | checkGetTrailingFile : function(rawfile) { 136 | var fileextention = FileDownload.getFileExtention(rawfile.substr(0,4)); 137 | switch(fileextention) { 138 | case 'jpg': 139 | if(rawfile.slice(-2) != "\xFF\xD9") { 140 | var appendedfile = rawfile.match(/^\xff\xd8\xff\xe0(?:[\s]|[^\s])+\xFF\xD9((?:[\s]|[^\s])+)$/i); 141 | return appendedfile; 142 | } 143 | break; 144 | case 'gif': 145 | //var a = rawfile.slice(-13); //\x00\x51\xFC\x1B\x28\x70\xA0\xC1\x83\x01\x01\x00\x3B 146 | if(rawfile.slice(-2) != "\x00\x3B") { 147 | var appendedfile = rawfile.match(/^GIF8(?:[\s]|[^\s])+\x00\x3B((?:[\s]|[^\s])+)$/i); 148 | if(appendedfile.length >= 2) 149 | return appendedfile[1]; 150 | } 151 | break; 152 | case 'png': 153 | if(rawfile.slice(-8) != "\x49\x45\x4e\x44\xae\x42\x60\x82") { 154 | var appendedfile = rawfile.match(/^\x89PNG(?:[\s]|[^\s])+\x49\x45\x4e\x44\xae\x42\x60\x82((?:[\s]|[^\s])+)$/i); 155 | if(appendedfile.length >= 2) 156 | return appendedfile[1]; 157 | } 158 | break; 159 | } 160 | return false; 161 | }, 162 | }; 163 | 164 | 165 | $(document).ready(function(){ 166 | // Initialisiere Drag&Drop EventListener 167 | var dropZone = document.getElementById('orgChartContainer'); 168 | dropZone.addEventListener('dragover', FileUpload.handleDragOver, false); 169 | dropZone.addEventListener('dragenter', FileUpload.handleDragEnter, false); 170 | dropZone.addEventListener('drop', FileUpload.handleUpload, false); 171 | }); 172 | 173 | -------------------------------------------------------------------------------- /js/notUglifiable.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | //Object inheritance: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain 5 | 'use strict'; 6 | 7 | class Setting { 8 | constructor(variablename, type, name, description) { 9 | // always initialize all instance properties 10 | this.variablename = variablename; 11 | this.type = type; 12 | this.name = name; 13 | this.description = description; 14 | } 15 | } 16 | 17 | class RangeSetting extends Setting { 18 | constructor(variablename, type, min, max, name, description) { 19 | super(variablename, type, name, description); 20 | this.min = min; 21 | this.max = max; 22 | } 23 | /*get area() { 24 | return this.height * this.width; 25 | } 26 | set sideLength(newLength) { 27 | this.height = newLength; 28 | this.width = newLength; 29 | }*/ 30 | } 31 | class DropDownSetting extends Setting { 32 | constructor(variablename, type, valueArray, name, description) { 33 | super(variablename, type, name, description); 34 | this.valueArray = valueArray; 35 | } 36 | } 37 | class MultiSetting extends Setting { 38 | constructor(variablename, type, valueArray, name, description) { 39 | super(variablename, type, name, description); 40 | this.valueArray = valueArray; 41 | } 42 | } 43 | class TextAreaSetting extends Setting { 44 | constructor(variablename, type, optionArray, name, description) { 45 | super(variablename, type, name, description); 46 | this.optionArray = optionArray; 47 | } 48 | } 49 | 50 | const permutator = (inputArr) => { 51 | let result = []; 52 | 53 | const permute = (arr, m = []) => { 54 | if (arr.length === 0) { 55 | result.push(m) 56 | } else { 57 | for (let i = 0; i < arr.length; i++) { 58 | let curr = arr.slice(); 59 | let next = curr.splice(i, 1); 60 | permute(curr.slice(), m.concat(next)) 61 | } 62 | } 63 | } 64 | 65 | permute(inputArr) 66 | 67 | return result; 68 | } 69 | -------------------------------------------------------------------------------- /js/timer.js: -------------------------------------------------------------------------------- 1 | 2 | var Timer = { 3 | 4 | overview : [], 5 | current : 0, 6 | iteration : 0, 7 | 8 | start : function() { 9 | if(this.current != 0) console.warn("! Timer.start var current != 0"); 10 | this.current = new Date().getTime(); 11 | }, 12 | stop : function(log) { 13 | var elapsed = new Date().getTime() - this.current; 14 | if(log) console.info("Step "+this.iteration+" - "+elapsed+"ms - "+log); 15 | this.current = 0; 16 | return elapsed; 17 | }, 18 | startN : function(name) { 19 | var start = new Date().getTime(); 20 | this.overview[name] = [start, 0]; 21 | }, 22 | stopN : function(name, log) { 23 | this.overview[name][1] = new Date().getTime() - this.overview[name][0]; 24 | if(log) console.info("Step "+this.iteration+" - "+this.overview[name][1]+"ms - "+log); 25 | return this.overview[name][1]; 26 | }, 27 | 28 | getIteration : function() { 29 | return this.iteration; 30 | }, 31 | 32 | incIteration : function() { 33 | this.iteration++; 34 | }, 35 | 36 | time_left : [], 37 | cinterval : [], 38 | countdown_timer_init : function(timeSec, elemID) { 39 | //The setInterval() method calls a function or evaluates an expression at specified intervals (in milliseconds). 40 | //The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed. 41 | this.cinterval[elemID] = setInterval("Timer.countdown_timer("+timeSec+",'"+elemID+"');", 1000); 42 | }, 43 | countdown_timer : function(timeSec, elemID) { //TODO: make this millisecond compatible for a cooler timer 44 | if(document.getElementById(elemID)) 45 | { 46 | if(timeSec && (typeof this.time_left[elemID] == 'undefined' || this.time_left[elemID] == 0)) { //Only to init timeSec once 47 | this.time_left[elemID] = timeSec; 48 | } 49 | 50 | // decrease timer 51 | this.time_left[elemID]--; 52 | document.getElementById(elemID).innerHTML = this.time_left[elemID]; 53 | if(this.time_left[elemID] == 0){ 54 | this.time_left[elemID] = 0; 55 | clearInterval(this.cinterval[elemID]); 56 | } 57 | } 58 | else 59 | { 60 | this.time_left[elemID] = 0; 61 | clearInterval(this.cinterval[elemID]); 62 | } 63 | }, 64 | countdown_timer_get : function(elemID) { 65 | return this.time_left[elemID]; 66 | }, 67 | countdown_timer_stop : function(elemID) { 68 | this.time_left[elemID] = 0; 69 | clearInterval(this.cinterval[elemID]); 70 | }, 71 | 72 | }; 73 | 74 | -------------------------------------------------------------------------------- /media/Mario_Coin.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/Mario_Coin.mp3 -------------------------------------------------------------------------------- /media/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/Roboto-Regular.ttf -------------------------------------------------------------------------------- /media/SCWF-current-cap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/SCWF-current-cap.png -------------------------------------------------------------------------------- /media/SCWF-example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/SCWF-example.gif -------------------------------------------------------------------------------- /media/SyllabaireMandombe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/SyllabaireMandombe.jpg -------------------------------------------------------------------------------- /media/Tengwar(Elvish).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/Tengwar(Elvish).png -------------------------------------------------------------------------------- /media/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/add.png -------------------------------------------------------------------------------- /media/alienese.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/alienese.png -------------------------------------------------------------------------------- /media/arrow2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/arrow2.png -------------------------------------------------------------------------------- /media/arrow3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/arrow3.png -------------------------------------------------------------------------------- /media/baudot-murray-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/baudot-murray-code.png -------------------------------------------------------------------------------- /media/bionicle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/bionicle.gif -------------------------------------------------------------------------------- /media/braille.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/braille.gif -------------------------------------------------------------------------------- /media/code39.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/code39.jpg -------------------------------------------------------------------------------- /media/code93.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/code93.png -------------------------------------------------------------------------------- /media/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/copy.png -------------------------------------------------------------------------------- /media/dancingmen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/dancingmen.png -------------------------------------------------------------------------------- /media/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/delete.png -------------------------------------------------------------------------------- /media/emblem.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/emblem.ico -------------------------------------------------------------------------------- /media/flagsemaphore.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/flagsemaphore.jpg -------------------------------------------------------------------------------- /media/gallifreyenalphabet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/gallifreyenalphabet.jpg -------------------------------------------------------------------------------- /media/gravityfalls.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/gravityfalls.jpg -------------------------------------------------------------------------------- /media/guess.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/guess.jpg -------------------------------------------------------------------------------- /media/hittitealphabet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/hittitealphabet.png -------------------------------------------------------------------------------- /media/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/loading.gif -------------------------------------------------------------------------------- /media/monkcipher.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/monkcipher.jpg -------------------------------------------------------------------------------- /media/nyctograph.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/nyctograph.jpg -------------------------------------------------------------------------------- /media/ogham.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/ogham.png -------------------------------------------------------------------------------- /media/pigpencipher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/pigpencipher.png -------------------------------------------------------------------------------- /media/refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/refresh.png -------------------------------------------------------------------------------- /media/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/save.png -------------------------------------------------------------------------------- /media/timesherald.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/timesherald.jpg -------------------------------------------------------------------------------- /media/vic_checkerboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/vic_checkerboard.jpg -------------------------------------------------------------------------------- /media/vic_checkerboard_ru.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaWouw/SCWF/676a7d9031228517befba8315630ef7c0449e04d/media/vic_checkerboard_ru.jpg --------------------------------------------------------------------------------