Base 64 Encoder (http basic authentication)

Former Member
Former Member
I've written a base 64 encoder, which is required for basic http authentication. I thought it might be useful for someone.

class Base64Encoder
{
hidden static const codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
hidden static const ascii = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";

static function encode(plain) {
var byteArray = toByteArray(plain);

var encoded = "";
var pos;

for (var i = 0; i < byteArray.size(); i += 3) {
pos = byteArray>> 2;
encoded += codes.substring(pos, pos + 1);
pos = (byteArray& 0x03) << 4;

if (i + 1 < byteArray.size()) {
pos += byteArray[i + 1] >> 4;
encoded += codes.substring(pos, pos + 1);
pos = (byteArray[i + 1] & 0x0F) << 2;

if (i + 2 < byteArray.size()) {
pos += byteArray[i + 2] >> 6;
encoded += codes.substring(pos, pos + 1);

pos = byteArray[i + 2] & 0x3F;
encoded += codes.substring(pos, pos + 1);
}
else {
encoded += codes.substring(pos, pos + 1);
encoded += "=";
}
}
else {
encoded += codes.substring(pos, pos + 1);
encoded += "==";
}
}

return encoded;
}

hidden static function toByteArray(text) {
var array = new[text.length()];
for (var i = 0; i < text.length(); i++) {
var pos = ascii.find(text.substring(i, i + 1));

if(pos == null) {
throw new UnknownCharException();
}

array= pos + 32;
}

return array;
}
}

class UnknownCharException extends Toybox.Lang.Exception
{
var char;

function initialize(char) {
Exception.initialize();
self.char = char;
}

function getErrorMessage() {
return Lang.format("Char $1$ is not supported", [char]);
}
}
[/CODE]

To use with json request, you need to first create a username/password hash:

var passwordString = Lang.format("$1$:$2$", [userName, password]);
passwordHash = Base64Encoder.encode(passwordString);



Then you need to add a headers dictionary to the options dictionary of your json request:

var headers = {"Content-Type" => Comm.REQUEST_CONTENT_TYPE_URL_ENCODED};

if (passwordHash != null) {
headers.put("Authorization", Lang.format("Basic $1$", [passwordHash]));
}

var options = { :method => Comm.HTTP_REQUEST_METHOD_GET,
:headers => headers};

Comm.makeJsonRequest(url, parameters, options, callback);


Of course you'll need to handle the UnknownCharException (for diacritics and other unsupported chars).

If you find this useful and decide to use it, a pm or reply is appreciated.
  • Former Member
    Former Member
    TeunMo thanks! I've used you code - that saved me some coding time. However, it would be better to change ASCII part to UTF8, probably with built-in converter, present in Garmin API (StringUtil class). I'm not complaining, it's just a note to those who will use this code as well :)