3

I found this strange JavaScript I cannot understand. The for cycle has a strange syntax (many parameters), can you explain me how it is intended to work? Thanks

decode: function(s){ for(var a, b, i = -1, l = (s = s.split("")).length, o = String.fromCharCode, c = "charCodeAt"; ++i < l; ((a = s[i][c](0)) & 0x80) && (s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ? o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "") ); return s.join(""); } 
0

4 Answers 4

5

That's an ordinary for loop, but with a very long var statement in the first part.

It's just like

var a, b, c; 

Also the iterator statement in the for loop contains a lot of operations instead of the loop actually having a body.

Either this function was written by a terrible programmer with no regard for readable code, or it has been intentionally minified and obfuscated.

Sign up to request clarification or add additional context in comments.

3 Comments

Or there was some performance win (real or imagined) to doing it that way.
@Codemonkey: No terrible programmer could have written that.
@SLaks You're wrong. A good programmer wouldn't set all those variables in there. A good programmer cares for readability.
2

interesting function, apparently trans-coding a certain set of chars, kind of esoteric and will only work with an ASCII code but here's the breakdown:

 for (var i = 0; i < s.length; i++) { var a = s.charCodeAt(i); if (a & 0x80) { // (a >= 128) if extended ascii var b = s.charCodeAt(i + 1); var specialA = (a & 0xfc) === 0xc0; // a IS [À, Á, Â or Ã] essentially [192, 193, 194, 195] var specialB = (b & 0xc0) === 0x80; // b >= 128 & b <= 191 eg. b is not a special Latin Ascii Letter if (specialA && specialB) { var txA = (a & 0x03) << 6; // [0, 64, 128, 192] var txB = b & 0x3f; // 0 - 63 s[i] = String.fromCharCode(txA + txB); } else { s[i] = String.fromCharCode(128); s[++i] = ""; } } } 

hope this helps, either way i found the decoding interesting, reminds of reading raw assembler, lol -ck

2 Comments

interesting decoding techniques n_n
Thank you, now it's very clear! This should be a function to decode unicode formatted strings (ie é should be decoded to é)
1

The different parts of the for loop is all there, divided by the semicolons (;).

The var part:

var a, b, i = -1, l = (s = s.split("")).length, o = String.fromCharCode, c = "charCodeAt"; 

The check part:

++i < l; 

The update part:

((a = s[i][c](0)) & 0x80) && (s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ? o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "") 

After the for() statement comes a ; right away, meaning that the loop doesn't have a body, but all the statements in the var-, check-, and update part will still be executed untill the check is no longer true.

Looks like someone didn't want their code to be readable. Where did you find it, anyway?

Comments

1

Breaking the loop into a one more readable:

  • rearranged loop parameters
  • changed (...)&&(...) with an if(...){(...)}
  • changed l to len
  • moved s = s.split(...) outside the len

.

var a, b, s = s.split(""), o = String.fromCharCode, c = "charCodeAt"; for(var i = -1, len = s.length; ++i < len;){ if((a = s[i][c](0)) & 0x80){ (s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ? o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = ""); } } 

  • changed i initial value and how/where it increases
  • moved a = s[i][c](0) outside

.

var a, b, s = s.split(""), o = String.fromCharCode, c = "charCodeAt"; for(var i = 0, len = s.length; i < len; i++){ a = s[i][c](0); if(a & 0x80){ s[i] = (a & 0xfc); (s[i] == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ? o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = ""); } } 

  • created tmp to make things easier to read
  • stored the ternary operation result in tmp
  • splitted (s[i] == 0xc0 && tmp, s[++i] = ""); with an if(...){s[++i] = "";}
  • replaced the new loop inside the your example

.

decode: function(s){ var tmp, a, b, s = s.split(""), o = String.fromCharCode, c = "charCodeAt"; for(var i = 0, len = s.length; i < len; i++){ a = s[i][c](0); if(a & 0x80){ s[i] = (a & 0xfc); if(((b = s[i + 1][c](0)) & 0xc0) == 0x80){ tmp = o(((a & 0x03) << 6) + (b & 0x3f)); }else{ tmp = o(128); } if(s[i] == 0xc0 && tmp){ s[++i] = ""; } } } return s.join(""); } 

Final result /\

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.