Search code examples
character-encodingtitaniumiso-8859-1

Convert string to ISO8859-1


Purpose

I have an external webservice that needs a sha1 password, but it stores it with the ISO8859-1 charset password. For example, the password é is stored as: 1599e9fa41ec68c80230491902786bee889f5bcb (this is the sha1 hash for é in iso).

However, what my app sends is the following hash:

bf15be717ac1b080b4f1c456692825891ff5073d (the sha1 hash for 'é' password in utf8)

So there is no way to change this behaviour :-(

Problem

What I want to do is to convert the typed password from utf8 to iso8859-1 Here is the code I use :

var buffer = Ti.createBuffer({length: 250});
var length = Ti.Codec.encodeString({
    source: 'é',
    dest: buffer,
    charset: Ti.Codec.CHARSET_ISO_LATIN_1
};

buffer.length = length;

var str = Titanium.Utils.sha1(buffer.toBlob());
alert(str);

This displays the following sha1 : "da39a3ee5..." which is the sha1 for empty string. The same code with 'e' as source displays "58e6b3a..." which is the sha1 for 'e'

Does anyone have an idea of what I do wrong or how I could do it right?


Solution

  • Hi I ran in a similar problem and found that the parameter 'type' in the Ti.Codec.encodeString() function solves my problem.

    In my case I used the ISO-8859-1 (LATIN_1) and the SHA256. By adding the parameter 'type', the HASH SHA256 was the expected. So the bellow code works for me:

    var myString = "é";
    var bytesTotal = myString.length;
    var myBuffer = Ti.createBuffer({
        length : bytesTotal
    });
    var numLen = Ti.Codec.encodeString({
        source : myString,
        dest : myBuffer,
        type : Ti.Codec.TYPE_BYTE,
        charset : Ti.Codec.CHARSET_ISO_LATIN_1
    }); 
    var strSHA256 = Ti.Utils.sha256(myBuffer.toBlob());
    

    I think for your code, you just should use the function 'sha1()' instead.

    UPDATED ANSWER!!!

    @Guile warned me that the code above worked on Android but not in iOS.

    I investigated a little more and I found the problem running this in iOS:

    var myString = "é";
    var bytesTotal = myString.length;
    var numLen = Ti.Codec.encodeString({
           source : myString,
           dest : myBuffer,
           type : Ti.Codec.TYPE_BYTE,
           charset : Ti.Codec.CHARSET_ISO_LATIN_1
       }); 
    

    In the code above, If you check the bytes in 'myBuffer' it will be the expected for LATIN_1 (ISO-8859-1).

    myBuffer.toBlob()
    

    But when it is converted Blob we have a problem. If you use the 'myBuffer.toBlob().text' an UTF-8 string will be produced and some kind of error happens because the output string is empty "".

    Probably is related to the LATIN_1 buffer being converted to UTF-8.

    Well, we need to convert to blob because the Ti.Utils.sha256() expected a string parameter (in UTF8) or a Blob parameter.

    We can't use the object 'myBuffer' directly in the function sha256(), because it does not accepts a parameter of the type Titanium.Buffer.

    So my solution was to found an alternative to the function Ti.Utils.sha256()

    var hash = CryptoJS.SHA256(CryptoJS.enc.Latin1.parse("é"));
    alert(hash.toString(CryptoJS.enc.Hex));
    

    You can found the CryptoJS code here: https://code.google.com/p/crypto-js/

    I just downloaded the file 'CryptoJS v3.1.2.zip' in the above link. Extracted it, copied and pasted the code of the file 'rollups/sha256.js'.

    It worked on Android Device and iOS Simulator.

    As I said before, It may work for you if you use the sha1() function (file 'rollups/sha1.js')