0
votes

I've been asked to implement and MD5 hasher ActionScript-3 and as I was in the middle of debugging how I formatted my input I came across a problem. When I try and output the ByteArray as a binary string using .toString(2), the toString(2) method will perform some short cuts that alter how the binary should look. For Example

var bytes:ByteArray = new ByteArray();
bytes.endian = Endian.LITTLE_ENDIAN;
bytes.writeUTFBytes("a");
bytes.writeByte(0x0);
var t1:String = bytes[0].toString(2); // is 1100001 when it should be 01100001
var t2:String = bytes[1].toString(2); // is 0 when it should be 00000000

so I guess my question is, might there a way to output a binary String from a ByteArray that will always shows each byte as a 8 bit block?

2
Either add 256 before you convert to a string, and then strip off the first digit, or manually prepend an appropriate number of zeroes afterwards. But why on earth do you need to create binary strings in order to do MD5? You're aware that ActionScript has perfectly adequate bitwise operators on uint already, right? - hmakholm left over Monica
Since you're already writing your own MD5 algorithm, why not write your own binary toString too? It's fairly simple. Also, have you seen this library? It includes a very fast MD5 function. - Cameron
I was using the binary string for debugging purposes, to make sure I had formatted my input correctly. - Nimnam1
If any of the answers solves your problem, kindly choose that as accepted answer. - danishgoel

2 Answers

1
votes

All you need is to pad the output of toString(2) with zeros on the left to make its length equal to 8. Use this function for padding

function padString(str:String, len:int, char:String, padLeft:Boolean = true):String{
    var padLength:int = len - str.length;
    var str_padding:String = "";
    if(padLength > 0 && char.length == 1)
        for(var i:int = 0; i < padLength; i++)
            str_padding += char;

    return (padLeft ? str_padding : "") + str + (!padLeft ? str_padding: "");
}

With this function the code looks like this and gives the correct output

var bytes:ByteArray = new ByteArray();
bytes.endian = Endian.LITTLE_ENDIAN;
bytes.writeUTFBytes("a");
bytes.writeByte(0x0);
var t1:String = padString(bytes[0].toString(2), 8, "0"); // is now 01100001
var t2:String = padString(bytes[1].toString(2), 8, "0"); // is now 00000000

Update
If you want to get a string representation of complete byteArray you can use a function which iterates on the byteArray. I have wrote the following function and it seems to work correctly. Give it a try

// String Padding function
function padString(str:String, len:int, char:String, padLeft:Boolean = true):String{
    // get no of padding characters needed
    var padLength:int = len - str.length;

    // padding string
    var str_padding:String = "";

    // loop from 0 to no of padding characters needed
    // Note: this loop will not run if padLength is less than 1 
    // as i < padLength will be false from begining
    for(var i:int = 0; i < padLength; i++)
        str_padding += char;

    // return string with padding attached either to left or right depending on the padLeft Boolean
    return (padLeft ? str_padding : "") + str + (!padLeft ? str_padding: "");
}

// Return a Binary String Representation of a byte Array
function byteArrayToBinaryString(bArray:ByteArray):String{
    // binary string to return
    var str:String = "";

    // store length so that it is not recomputed on every loop
    var aLen = bArray.length;

    // loop over all available bytes and concatenate the padded string to return string
    for(var i:int = 0; i < aLen; i++)
        str += padString(bArray[i].toString(2), 8, "0");

    // return binary string
    return str;
}

Now you can simply use the byteArrayToBinaryString() function like this:

// init byte array and set Endianness
var bytes:ByteArray = new ByteArray();
bytes.endian = Endian.LITTLE_ENDIAN;

// write some data to byte array
bytes.writeUTFBytes("a");
bytes.writeByte(0x0);

// convert to binaryString
var byteStr:String = byteArrayToBinaryString(bytes); // returns 0110000100000000
-1
votes

Here is a function extended on the Hurlant library to handle hashing byteArray.
This class has a learning curve but once you get it you will love it.

As far as your ByteArray issue with toString. I know the toString method is not accurate For this very reason.
You might want to look into byteArray.readMultiByte that will give you the 01 you are looking for. Although I can't seem top get it to work on my sample code either lol
I just always get a and empty string.

var bytes:ByteArray = new ByteArray();
bytes.endian = Endian.LITTLE_ENDIAN;
bytes.writeUTFBytes("a");
bytes.writeByte(0x0);
bytes.position = 0
var t1:String = bytes.readMultiByte(1,'us-ascii'); // is 1100001 when it should be 01100001
trace(t1)
var t2:String = bytes.readMultiByte(1,'iso-8859-01'); // is 0 when it should be 00000000
trace(t2)