views:

63

answers:

1

I'm using tiled to create a tile map. (Tiled is a tile map editor with support for orthogonal and isometric maps)

It saves the map in an XML file. It can use certain encoding structures:

  • regular base64
  • base64 + gzip
  • base64 + zlib
  • regular csv

Now, I've completely given up on gzip (my server gzips traffic it anyway, so no loss there) So I thought I'd try regular base64 decoding, using a base64 jquery plugin

But the data comes out all garbled, like this:

��������������������������������������������������������

I guess it's binary encoding it, but how do I get around that?

Example data that needs to be decoded (regular base64):

jQAAAI4AAACPAAAAkAAAAJEAAACSAAAAkwAAAKEAAACiAAAAowAAAKQAAAClAAAApgAAAKcAAAA=

Example data that needs to be decoded (gzipped base64):

H4sIAAAAAAAACw3DhwnAMAwAMP8P2Rdk9s1KoBQR2WK12R1Ol9vj9fn5A/luZ4Y4AAAA

Example data as csv:

141,142,143,144,145,146,147,
161,162,163,164,165,166,167

So how can I turn the regular base64 encoded bit and turn it into the csv?

Edit:

Using the solution Pointy found I got a semi-correct array. After a few thousand characters the 2 numbers would be wrong again, though. And even more frequent after that.

I then found someone who also uses tiled and the base64 encoding in his scheme. After he decoded the array, he also did this to it:

        var d = base64_decode($(this).find('data').text());
    var e = new Array();
    for (var i = 0; i <= d.length; i += 4) {
    var f = d[i] | d[i + 1] << 8 | d[i + 2] << 16 | d[i + 3] << 24;
    e.push(f)
    }

I have no idea why this is needed, but at least it works. If anyone could explain, please do!

+2  A: 
Pointy
That worked.Only every fourth number in the array is correct, though. I can iterate through that, no problem.However, after a certain amount of numbers they're wrong again.Like: 41,42,43,44,44,41,44,41,4096,12288should be: 41,42,43,44,44,41,44,41,225,226,227How did that happen?
skerit
Hmm well it could be that the base-64 data is being decoded but then the Unicode nature of String values is getting in your way. Since you really want to treat the bytes as raw numeric values, you might be better off with a custom decoder. I was playing with a Javascript base-64 decoder, it so happens, just a few days ago. I'll look for it.
Pointy
Allright, thanks!So, to clarify: the first 522 numbers are correct.
skerit
Almost there!It seems much more correct time, but unwanted bits still sneak in. The first time this happens is after 623 characters (without the unwanted 0) This is the way it should go: 14,11,255,256,257,11,12,13,14,14 and this is what it turned in to: 14,11,255,0,1,11,12,13,14,14So for a small decode this works perfectly, but it gives strange results when things get bigger.
skerit
Well if the values are encoded properly, I'm not sure how this can not work.
Pointy
Also note that you can't encode the number 256 in a single byte! The result numbers will be in the range 0 to 255. That's all that a byte can hold.
Pointy
Oh, so that was the problem!?Because 256 would become 0, 257 1, ... It just looped around?I found something that fixed (and added it to the question), but I don't really know how it fixed it.
skerit
Yes. Base64 encoding is all about encoding 8-bit values (0 ... 255). Thus it's impossible to get anything *out* of an encoded string except a series of 8-bit values.
Pointy
Well, doing ` for (var i = 0; i <= source.length; i += 4) { var tempTile = source[i] | source[i + 1] << 8 | source[i + 2] << 16 | source[i + 3] << 24; destination.push(tempTile) }` on the result of the decode fixed it ...
skerit