<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -11,7 +11,7 @@ config.whiny_nils = true
 # Show full error reports and disable caching
 config.action_controller.consider_all_requests_local = true
 config.action_view.debug_rjs                         = false
-config.action_controller.perform_caching             = false
+config.action_controller.perform_caching             = true
 
 # Don't care if the mailer can't send
 config.action_mailer.raise_delivery_errors = false
\ No newline at end of file</diff>
      <filename>config/environments/development.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,8 +6,6 @@
  *
  *--------------------------------------------------------------------------*/
 
-var shackeronly = true
-
 var Prototype = {
   Version: '1.6.0.3',
 
@@ -5792,59 +5790,30 @@ Observed = Behavior.create({
 });
 
 
-function test_extensions() {
-  var tmp = characters
-  characters = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;, &quot;e&quot;, &quot;f&quot;, &quot;g&quot;, &quot;h&quot;, &quot;i&quot;, &quot;j&quot;, &quot;k&quot;, &quot;l&quot;, &quot;m&quot;, &quot;n&quot;, &quot;o&quot;, &quot;p&quot;, &quot;q&quot;, &quot;r&quot;, &quot;s&quot;, &quot;t&quot;, &quot;u&quot;, &quot;v&quot;, &quot;w&quot;, &quot;x&quot;, &quot;y&quot;, &quot;z&quot;, &quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;, &quot;F&quot;, &quot;G&quot;, &quot;H&quot;, &quot;I&quot;, &quot;J&quot;, &quot;K&quot;, &quot;L&quot;, &quot;M&quot;, &quot;N&quot;, &quot;O&quot;, &quot;P&quot;, &quot;Q&quot;, &quot;R&quot;, &quot;S&quot;, &quot;T&quot;, &quot;U&quot;, &quot;V&quot;, &quot;W&quot;, &quot;X&quot;, &quot;Y&quot;, &quot;Z&quot;];
-  console.log(&quot;test_string_last();&quot;)
-  test_string_last();
-  console.log(&quot;test_string_is_highest();&quot;)
-  test_string_is_highest();
-  console.log(&quot;test_string_increment();&quot;)
-  test_string_increment();
-  console.log(&quot;test_string_increment_last();&quot;)
-  test_string_increment_last();
-  console.log(&quot;test_string_next_chunk();&quot;)
-  test_string_next_chunk();
-  evaluate_test_results();
-  characters = tmp
+// Centers the absolute div for flash messages
+function centerflash(id) {
+  if (screen &amp;&amp; screen.availWidth &amp;&amp; $(id) &amp;&amp; $('container')) {
+    containerleft = $('container').makePositioned().cumulativeOffset($(id)).first();
+    containerwidth = $('container').getDimensions()['width'];
+    $(id).setStyle({left: (containerleft + (containerwidth - $(id).getDimensions()['width']) / 2) + &quot;px&quot;});
+  }
 }
 
 // Returns last character of a string
 String.prototype.last = function() {
   return this.charAt(this.length-1)
 };
-function test_string_last() {
-  assert_equal(&quot;a&quot;, &quot;a&quot;.last());
-  assert_equal(&quot;B&quot;, &quot;aB&quot;.last());
-  assert_equal(&quot;f&quot;, &quot;ASDf&quot;.last());
-  assert_equal(&quot;&quot;, &quot;&quot;.last());
-}
 
 // Indicates, whether a character is the highest
 String.prototype.is_highest = function() {
   return this == characters.last();
 };
-function test_string_is_highest() {
-  assert_equal(&quot;a&quot;, characters.first());
-  assert_equal(&quot;Z&quot;, characters.last());
-  assert_equal(false, &quot;a&quot;.is_highest());
-  assert_equal(true, &quot;Z&quot;.is_highest());
-  assert_equal(false, &quot;&quot;.is_highest());
-}
 
 // Increments a character by one (returns lowest character if not found)
 String.prototype.increment = function() {
   if (this.is_highest()) return characters.first();  // If already highest character, return lowest character
   return characters[characters.indexOf(String(this)) + 1];   // Else, increment character by one
 }
-function test_string_increment() {
-  assert_equal(&quot;b&quot;, &quot;a&quot;.increment());
-  assert_equal(&quot;A&quot;, &quot;z&quot;.increment());
-  assert_equal(&quot;a&quot;, &quot;Z&quot;.increment());
-  assert_equal(&quot;a&quot;, &quot;!&quot;.increment());
-  assert_equal(&quot;a&quot;, &quot;abc&quot;.increment());
-  assert_equal(&quot;a&quot;, &quot;&quot;.increment());
-}
 
 // Increments only the last character of a string
 String.prototype.increment_last = function() {
@@ -5852,13 +5821,6 @@ String.prototype.increment_last = function() {
   if (this.length == 1) return this.increment();
   return this.slice(0, this.length - 1) + this.last().increment();
 };
-function test_string_increment_last() {
-  assert_equal(&quot;b&quot;, &quot;a&quot;.increment_last());
-  assert_equal(&quot;aC&quot;, &quot;aB&quot;.increment_last());
-  assert_equal(&quot;ASDg&quot;, &quot;ASDf&quot;.increment_last());
-  assert_equal(&quot;asdasdasdasdasda&quot;, &quot;asdasdasdasdasdZ&quot;.increment_last());
-  assert_equal(&quot;&quot;, &quot;&quot;.increment_last());
-}
 
 // Increments a chunk according to the given characters
 String.prototype.next_chunk = function() {
@@ -5883,18 +5845,6 @@ String.prototype.next_chunk = function() {
     }
     return characters.first().times(size + 1)  // Every character is highest, add one character and return everything lowest
   }
-  
-}
-function test_string_next_chunk() {
-  assert_equal(&quot;a&quot;, &quot;&quot;.next_chunk());
-  assert_equal(&quot;aa&quot;, &quot;Z&quot;.next_chunk());
-  assert_equal(&quot;y&quot;, &quot;x&quot;.next_chunk());
-  assert_equal(&quot;abce&quot;, &quot;abcd&quot;.next_chunk());
-  assert_equal(&quot;abcy&quot;, &quot;abcx&quot;.next_chunk());
-  assert_equal(&quot;abda&quot;, &quot;abcZ&quot;.next_chunk());
-  assert_equal(&quot;aaaabaaab&quot;, &quot;aaaabaaaa&quot;.next_chunk());
-  assert_equal(&quot;aaaabaaaa&quot;, &quot;aaaaaZZZZ&quot;.next_chunk());
-  assert_equal(&quot;aaaa&quot;, &quot;ZZZ&quot;.next_chunk());
 }
 
 
@@ -6026,46 +5976,74 @@ function SHA256(s){
  
 }
 
-var step = -1
-var secret
-var chunk
-var characters = []
-var counter = 0
-
-function setup() {
-  if (!secret.empty() &amp;&amp; characters.length &gt; 0 &amp;&amp; !chunk.empty()) {
-    $('setup').insert('Secret: ' + secret + '&lt;br/&gt;');
-    $('setup').insert('Initial password: &quot;' + chunk + '&quot;&lt;br/&gt;');
-    setTimeout(function() { shacker() }, 10);
-  }
+// Keeping track of how many passwords we tried.
+// We want to send this to the server in our report intervals
+counter = 0;
+
+// You may want to override this if you are creating a widget.
+function start_shacker() {
+  console.log(&quot;Starting algorithm.&quot;);
+  shacker();
 }
 
+// This is the main brute force algorithm
 function shacker() {
-  if (secret.empty() || characters.length == 0 || chunk.empty()) return;
+  if (secret.empty()) return;
   counter++;
+  
   if (secret == SHA256(chunk)) {
-    return report(chunk);
+    // Congratulations, you found it
+    return solution(chunk);
+    
   } else {
-    chunk = chunk.next_chunk();
-    if (counter % 1000 == 0) {
-      $('status').update(counter);
-      setTimeout(function() { shacker() }, 10);
+    
+    
+    // Nothing found yet, let's try the next password
+    if (chunk == last_chunk || chunk.length &gt; length) {
+      // Start from the beginning, when ran out of password space
+      chunk = first_chunk;
+      console.log('Starting at ' + chunk)
     } else {
-      shacker();
+      // Increment the chunk by one if we're somewhere in the middle
+      chunk = chunk.next_chunk();    
+    }
+    
+    // Hand in a report
+    if (report_interval &gt; 0 &amp;&amp; counter % report_interval == 0) {
+      report(counter)
+    }
+    
+    // Update status message every status_interval tries
+    if (counter % status_interval == 0) {
+      status();
+      setTimeout(function() { shacker() }, status_delay);
+      
+    // Continue
+    } else {
+      //console.log(chunk);
+      if (loop_delay &gt; 0) {
+        setTimeout(function() { shacker() }, loop_delay);        
+      } else {
+        shacker();
+      }
     }
   }
 }
 
-function report(password) {
-  alert('I found it: ' + password);
+// Updating the &lt;div id=&quot;status&quot;&gt;&lt;/div&gt;
+function status() {
+  if (!$('status')) return;
+  $('status').update(&quot;: &quot; + counter + &quot; &quot; + (counter / realm) + &quot;% &quot; + first_chunk + &quot;-&quot; + chunk);
 }
 
-function centerflash(id) {
-  if (screen &amp;&amp; screen.availWidth &amp;&amp; $(id) &amp;&amp; $('container')) {
-    containerleft = $('container').makePositioned().cumulativeOffset($(id)).first();
-    containerwidth = $('container').getDimensions()['width'];
-    $(id).setStyle({left: (containerleft + (containerwidth - $(id).getDimensions()['width']) / 2) + &quot;px&quot;});
-  }
+// Send interval report
+function report(counter_to_report) {
+  console.log('Reporting &quot;' + counter_to_report + '&quot;');
+  new Ajax.Request(report_url.sub('COUNTERPLACEHOLDER', counter_to_report), {asynchronous:true});
 }
 
-
+// Redirect to solution page
+function solution(password) {
+  console.log('Handing in solution &quot;' + password + '&quot;');
+  window.location.href = solution_url.sub('PASSWORDPLACEHOLDER', encodeURIComponent(String.interpret(password)));
+}</diff>
      <filename>public/javascripts/shacker.js</filename>
    </modified>
    <modified>
      <diff>@@ -12,6 +12,7 @@ html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pr
 html { font-size:12px; color:#222; font-family:&quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; }
 a, a:visited, a:active, a:hover, a:focus { text-decoration: none; color: #f90; }
 h1 { font-weight: bold; font-size:20px; line-height:1; padding-bottom: 14px; }
+h2 { font-weight: bold; font-size:15px; line-height:1; padding-bottom: 14px; }
 body { margin-top: 50px; }
 
 /* Structure */
@@ -23,6 +24,32 @@ div#container {
   background: #eee;
 }
 
+div#solution {
+  text-align: center;
+  font-weight: bold; font-size:40px; line-height:1; padding-bottom: 14px;
+  color: red;
+}
+
+span#status { word-spacing:2em; }
+div#busy { float:right; }
+
+/* Admin */
+
+input#reset_settings { color: red; }
+div#statistics { padding: 30px; }
+div.tcol {font-weight: bold;}
+div.attacks { width: 900px; background-color: yellow;}
+div.attack { float:left }
+div.id         { width: 34px; }
+div.position   { width: 34px; }
+div.offset     { width: 80px; }
+div.chunk      { width: 70px; }
+div.client     { width: 80px; }
+div.created_at { width: 140px; }
+div.updated_at { width: 140px; }
+div.response   { font-weight: bold; width: 70px;}
+div.timespan   { font-weight: bold; }
+
 /* Flash messages */
 
 div#flash-notice { background: #7f7; }</diff>
      <filename>public/stylesheets/shacker.css</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>54d4b8342cd99c4ef0582ef276ac2cdda89a95cb</id>
    </parent>
  </parents>
  <author>
    <name>Commander Keen</name>
    <email>nom@ximus.de</email>
  </author>
  <url>http://github.com/funkensturm/shacker/commit/ea6379d250508f122b2c2e0c38e6b94b5eb75877</url>
  <id>ea6379d250508f122b2c2e0c38e6b94b5eb75877</id>
  <committed-date>2009-11-10T14:12:28-08:00</committed-date>
  <authored-date>2009-11-10T14:12:28-08:00</authored-date>
  <message>quick deploy</message>
  <tree>e5b99cb76e1d5f29809881073495a37a65c5d96e</tree>
  <committer>
    <name>Commander Keen</name>
    <email>nom@ximus.de</email>
  </committer>
</commit>
