Archive for February, 2012

Make Magnet Links Work in Firefox

Since The Pirate Bay dropped torrent files and started only providing magnet links the other day it became quickly annoying that Firefox wouldn’t open them or associate them with my torrent client. The error message one encounters is:

Firefox doesn't know how to open this address, because the protocol (magnet) isn't associated with any program

The solution is to open about:config and add this key:

network.protocol-handler.expose.magnet (boolean) false

Now when you click on a magnet: link you will be prompted to select an application to open it with. In my case I added /usr/bin/vuze and checked the remember box.

Implementing One-Time Pads in JavaScript

I have always been fond of the One-Time Pad. There are a lot of paranoid people who think admins have nothing better to do than sit around reading private messages all day and I thought it would be neat (even if never used) to implement client-side OTP encryption. Not having the time to do this kind of thing myself I asked Tucker, a programmer who helps moderate Yiffy International if he would like to contribute the code. Fortunately for us he did, and he is graciously allowing me to re-post it here for your pleasure.

It should be noted that using the built in pad generator is the least secure method since it is easy to predict that pads generated with it used a browser’s RNG.

The particularly clever thing about this implementation is that special characters, numbers and spaces – even line breaks – are preserved through a mechanism we call “Z-encoding.”

Thanks Tucker, that’s super cool!

Here is the JavaScript element:

function format (string) {
  var retval = string.charAt (0);
  for (var i = 1; i < string.length; i ++) {
    if ((i % 48) == 0) retval += "\n";
    else if ((i % 6) == 0) retval += " ";
    retval += string.charAt (i);
  }
  return retval;
}

function unformat (string) {
  string = string.toUpperCase ();
  var retval = "";
  for (var i = 0; i < string.length; i ++) {
    if ((string.charCodeAt (i) >= 65) && (string.charCodeAt (i) <= 90)) {
      retval += string.charAt (i);
    }
  }
  return retval;
}

function checkformat (string) {
  for (var i = 0; i < string.length; i ++) {
    if ((string.charCodeAt (i) < 65) || (string.charCodeAt (i) > 90)) {
      return true;
    }
  }
  return false;
}

function inttoletters (number) {
  var bigbyte = Math.floor (number / 16);
  var smallbyte = number - (bigbyte * 16);
  return String.fromCharCode (65 + bigbyte, 65 + smallbyte);
}

function letterstoint (letter1, letter2) {
  var bigbyte = letter1 - 65;
  var smallbyte = letter2 - 65;
  return String.fromCharCode ((16 * bigbyte) + smallbyte);
}

function process (source) {
  source = source.toUpperCase ();
  var retval = "";
  for (var i = 0; i < source.length; i ++) {
    if ((source.charCodeAt (i) >= 65) && (source.charCodeAt (i) < 90)) {
      retval += source.charAt (i);
    } else if (source.charCodeAt (i) == 90) {
      retval += "ZZ";
    } else {
      retval += "Z" + inttoletters (source.charCodeAt (i));
    }
  }
  return retval;
}

function unprocess (source) {
  var retval = "";if (checkformat (source)) {
    dispmsg ("Error: Invalid characters in source string.");
    return "";
  } else {
    for (var i = 0; i < source.length; i ++) {
      if ((source.charCodeAt (i) >= 65) && (source.charCodeAt (i) < 90)) {
        retval += source.charAt (i);
      } else if (source.charCodeAt (i) == 90) {
        i ++;
        if (source.charCodeAt (i) == 90) {
          retval += source.charAt (i);
        } else {
          retval += letterstoint (source.charCodeAt (i), source.charCodeAt (i + 1));
          i ++;
        }
      }
    }
    return retval.toLowerCase ();
  }
}

function genprs (source) {
  var retval = "";
  if (checkformat (source)) {
    dispmsg ("Error: Invalid characters in source string.");
    return "";
  } else {
    for (var i = 0; i < source.length; i ++) {
      retval += String.fromCharCode (65 + Math.floor (Math.random () * 26));
    }
    dispmsg ("Ready.");
    return retval;
  }
}

function encrypt (source, pad) {
  var retval = "";
  var newchar = 0;
  if (checkformat (source)) {
    dispmsg ("Error: Invalid characters in source string.");
    return "";
  } else if (source.length > pad.length) {
    dispmsg ("Error: Too many characters in source string.");
    return "";
  } else {
    while (pad.length > source.length) source += String.fromCharCode (65 + Math.floor (Math.random () * 25));
    for (var i = 0; i < source.length; i ++) {
      newchar = source.charCodeAt (i) + pad.charCodeAt (i) - 65;
      if (newchar > 90) newchar -= 26;
      retval += String.fromCharCode (newchar);
    }
    dispmsg ("Ready.");
    return retval;
  }
}

function decrypt (source, pad) {
  var retval = "";
  var newchar = 0;
  if (source.length > pad.length) {
    dispmsg ("Error: Too many characters in source string.");
    return "";
  } else {
    for (var i = 0; i < source.length; i ++) {
      newchar = source.charCodeAt (i) - pad.charCodeAt (i) + 65;
      if (newchar < 65) newchar += 26;
      retval += String.fromCharCode (newchar);
    }
    dispmsg ("Ready.");
    return retval;
  }
}

function fullencrypt (source, pad) {
  return format (encrypt (process (source), unformat (pad)));
}

function fulldecrypt (source, pad) {
  return unprocess (decrypt (unformat (source), unformat (pad)));
}

function html_generate () {
  document.getElementById ("pad").value = format (genprs (process (document.getElementById ("sender").value)));
}

function html_format () {
  document.getElementById ("pad").value = format (unformat (document.getElementById ("pad").value));
}

function html_copypad () {
  document.getElementById ("pastepad").value = document.getElementById ("pad").value;
  document.getElementById ("reciever").value = document.getElementById ("sender").value;
}

function html_encrypt () {
  document.getElementById ("sender").value = fullencrypt (document.getElementById ("sender").value, document.getElementById ("pad").value);
}

function html_decrypt () {
  document.getElementById ("reciever").value = fulldecrypt (document.getElementById ("reciever").value, document.getElementById ("pastepad").value);
}

function dispmsg (msgcode) {
  document.getElementById ("message").innerHTML = msgcode;
}

Here is a demo HTML form:

<html>
<head>
<title>Encryption Demo</title>
<style>textarea { resize: none !important; } #message { color: red; }</style>
<script type="text/javascript" src="encrypt.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body>
<table><tr>
<td>Sender: <input onclick="html_encrypt()" type="button" value="Encrypt" /></td>
<td>One Time Pad: <input onclick="html_generate()" type="button" value="Generate" /> <input onclick="html_format()" type="button" value="Format" /></td>
</tr><tr>
<td><textarea id="sender" cols="80" rows="20"></textarea></td>
<td><textarea id="pad" cols="80" rows="20"></textarea></td>
</tr><tr>
<td>Reciever: <input onclick="html_decrypt()" type="button" value="Decrypt" /></td>
<td>Paste One Time Pad: <input onclick="html_copypad()" type="button" value="Copy Pad" /></td>
</tr><tr>
<td><textarea id="reciever" readonly="readonly" cols="80" rows="20"></textarea></td>
<td><textarea id="pastepad" readonly="readonly" cols="80" rows="20"></textarea></td>
</tr></table>
<span id="message">Ready.</span>
</body>
</html>

You can read more about our implementation at: http://forum.yiffy.tk/viewtopic.php?f=2&t=3712.

Heart-Stopping Cheese Sauce in Under 5 Minutes

Making cheese sauce is a delicate process but you should have no trouble producing a smooth, consistent result if you follow these steps.

I don’t cook with measurements but the ratios are something like this: one part flour to one part butter, six parts milk and five+ parts cheese. It is important to have your cheese grated beforehand since this is a time-sensitive procedure.


Melt the butter on medium low until it begins to lightly bubble.

Whisk in your flour and stir consistently. Let the mixture thicken a little; it will yellow slightly but you do not want it to darken much. This is called a blond roux.

Slowly stir in cold milk with the roux. At first the consistency will be very thin, keep cooking until it thickens to about the same viscosity the roux had. Under-stirring will cause milk to crust, break off and form lumps in your sauce so pay attention! At the same time you want to gently raise the temperature of the sauce base until it is steaming hot. Remove from heat when you feel it is about half as thick as the sauce you want to make.

Slowly stir in your cheese to taste. It will disappear quickly, but if the sauce becomes too cold it is safe to put the burner on very low.

Now you may season your sauce to taste. Salt is not necessarily required if you are using a good old cheddar and salted butter. I like to add a little onion powder to give it character. Traditionally, fine ground white pepper is used in lighter sauces but I put fresh cracked black pepper in virtually everything; I think it tastes better and it makes the sauce look pretty swanky!

You may now turn your delicious, healthy vegetables…

into the massive heart failure they were always meant to be!

Delish!

Return top
foxpa.ws
Online Marketing Toplist
Internet
Technology Blogs - Blog Rankings

Internet Blogs - BlogCatalog Blog Directory

Bad Karma Networks

Please Donate!


Made in Canada  •  There's a fox in the Gibson!  •  2010-12