Numerical Methods and ASCII in AcroJS

Let’s raise the (disturbing) subject of bugs in Acrobat, I should point out one problem that could very well cause you grief if you ever try to do any numerical operations on character values in strings. For example, if you were to want to do string encryption or data compression, you might end up fighting some unusual gremlins. Let me start by telling you how things OUGHT to work; then we’ll see how things really are.

Getting ASCII value from character code

To get the numerical (ASCII) value of a character code in JavaScript, you have to use the charCodeAt() method of the String class.


var asciiValue = 'e'.charCodeAt(0); // asciiValue is 101

The argument to charCodeAt() is the offset, in the string, of the character whose

value you’re interested in.

Getting character code from ASCII value

To go the other direction (i.e., to create a character from a number), you have to use

the static String method, fromCharCode():


var str = new String;
str += String.fromCharCode(101); // str contains 'e'

In theory, then, you ought to be able to do a simple math operation on a character string

in order to encrypt it. Let’s say you want to XOR (exclusive-OR) each character against 15,

hex 0x0F. In theory, you could do:


var encrypted = new String;
var tmp = 0.0;

for (var i = 0; i < str.length; i++) {
tmp = str.charCodeAt(i); // get numeric value
tmp ^= 0x0F; // XOR
encrypted += String.fromCharCode(tmp);
}

Since XOR is bijective (reversible; toggle-able), giving back the original value after

using it twice in a row, you should be able to run a string through the above code twice and

get back the original string. In theory.

In reality, there’s a horrible problem. In Acrobat’s implementation of JavaScript,

charCodeAt() returns a signed value…whereas fromCharCode() requires an

unsigned value.

In Acrobat, a ‘high bit ASCII code’ (i.e., any character with a value over 127) comes

back from charCodeAt() with a negative value. This is in stark contrast to the

behavior of the JavaScript engine in Netscape 3.x and 4.x browsers. In those browsers,

charCodeAt() returns only positive values, never a negative value.

In theory, it shouldn’t matter for the example given above, since XOR is a bitwise

operation and should produce the same result on a given bit pattern, whether it’s later

interpreted signed or unsigned. BUT… the above loop code doesn’t seem to work (for me, on

Acro 4.05/Mac). If you find otherwise, let me know.

You May Also Like

About the Author: Kas Thomas

Leave a Reply