=^.^=

TypeError: Object #<an HTMLObjectElement> has no method 'create'

karma

If you're running web software that bridges with Flex you will need to update the FABridge.js file to avoid errors like the one above with modern browsers.

Download your copy of the latest SDK from http://opensource.adobe.com/wiki/display/flexsdk/Flex+SDK and do a simple drop-in replacement from frameworks/javascript/fabridge/src/bridge/.

Raspberry Pi Update

karma

The first run of Raspberry Pis sold out in a matter of seconds. Farnell and RS are now going through their long list of backorderers. I received this 3 days ago:

Farnell/Newark/Element14/whatever the hell ever won't begin shipping until June for we stragglers who were a couple hours late. The pre-order gives me a CAD price of $48something and the only shipping option for Canadians at the time is $12. The whole appeal of this thing is that it's supposed to be a $35 computer; I'm quite sure I can put my $60 to much better use in the three months I'd be sitting on my hands waiting for it anyway.

Thanks but no thanks.

So far it seems like they have their operation together a little better than RS, but time will tell who will actually be ready to ship first. I received this today:

Dear Customer

Thank you for joining the Raspberry Pi revolution and registering your interest in Raspberry PiÂ’s Model B board from RS Components.

We have received extraordinary levels of demand for this product. To help ensure as many people as possible can experience the Raspberry Pi concept, we are initially limiting boards to one per customer, and we will send you regular updates on availability. As boards arrive into stock, they will be allocated on a first-come first-serve basis, in order of when requests were received.

Thank you for your patience; we will be in touch as soon as possible with more details.

Not holding my breath.

Raspberry Pi Launched, Still Won't Be Out Forever

karma

I registered with both vendors supplying the new Raspberry Pi only hours after they announced the launch. While I still haven't heard from Premier Farnell, RS has been running through the long list of other contenders today. I received this minutes after a friend in the UK:

Dear Customer

Thank you for joining the Raspberry Pi revolution and registering your interest in Raspberry PiÂ’s Model B board from RS Components.

We have received extraordinary levels of demand for this product. To help ensure as many people as possible can experience the Raspberry Pi concept, we are limiting boards to one per customer, and we will send you further information on your request in the next seven days. Once we receive the boards into stock, they will be allocated on a first-come first-serve basis, in order of when requests were received.

Thank you for your patience; we will be in touch as soon as possible with more details.

RS Components

I'm not expecting anything different from Farnell.

As I suspected from the outset, demand would be "much higher than we predicted!" and these babies may go like hotcakes on ebay.

Make Magnet Links Work in Firefox

karma

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

karma

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.