Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I made simple JavaScript xor function. It accepts string, numeric array and mixed array (char, string, num) as params. It returns string or an array.

Returning an array is a must!. All numbers are printable on screen and there is no potential loss of information. String works excellent if you pass it in a variable. But if you want to print it on screen, there might be some unprintable characters in a string. Like \n \t \cr \lf, or whole array of unprintable unicode char's.

Also array as password is also needed because that's an easy way to have low numbers like [0,1,2,3...] which are not so easy to represent as a string.

My questions are the usual. What do you think of it? Does any improvement come in mind when you look at the code? Did I miss something? Any potential bugs?

/*
    source: string, [1,2,3,...], ['a', 'b', 'c', ...], [1, 'a', 2, 'b', ...]
    password: string, [1,2,3,...], ['a', 'b', 'c', ...], [1, 'a', 2, 'b', ...]
    return type str || []

*/

function xor(source, password, return_type) {
  var ret_ar = [],
    i, len,
    pwlen,
    pwindex = 0,
    s, p;
  if(typeof source === 'string') {
    source = source.split('');
  }
  if(Object.prototype.toString.call(source) === '[object Array]') {
    for(i = 0, len = source.length; i < len; ++i) {
      s = source[i];
      if(typeof s === 'string') {
        source[i] = s.charCodeAt(0);
      } else if(typeof s !== 'number') {
        console.log(s);
        throw("Only str or [number, 'c', 'h',...] in xor \n Bad first param in function xor:" + s);
      }
    }
  } else {
    throw('Very Bad first param in function xor:' + source);
  }
  if(typeof password === 'string') {
    password = password.split('');
  }
  if(Object.prototype.toString.call(password) === '[object Array]') {
    for(i = 0, len = password.length; i < len; ++i) {
      p = password[i];
      if(typeof p === 'string') {
        password[i] = p.charCodeAt(0);
      } else if(typeof p !== 'number') {
        console.log(p);
        throw("Only str or [number, 'c', 'h',...] in xor \n Bad second param in function xor:" + p);
      }
    }
  } else {
    throw('Very Bad second param in function xor:' + p);
  }
  pwindex = 0;
  pwlen = password.length - 1;
  len = source.length;
  if(pwlen >= 0) {
    for(i = 0; i < len; ++i) {
      ret_ar[i] = source[i] ^ password[pwindex]; // unefined ^7 === 7
      if(pwindex >= pwlen) pwindex = 0;
      else ++pwindex;
    }
  } else // ~source on '', undefined passwprd
  {
    for(i = 0; i < len; ++i) {
      ret_ar[i] = ~source[i]; // ~unefined === -1
    }
  }
  source = password = i = pwlen = pwindex = null;
  //debugger;
  if(typeof return_type === 'string') {
    // code -> char . join('')
    return ret_ar.map(function (code) {
      return String.fromCharCode(code)
    }).join('');
  } else {
    return ret_ar;
  }
} // ------------------------- end xor () ----------------------------

Here are tests for function if anyone need it.

out = document.getElementById('my_div');

var str = JSON.stringify(pitanja_ar);
var str = 'small test';
var pass = 'password';
var p_ar = [0,1,2,3,4,5];

out.innerHTML = '';
out.innerHTML += '1.<br> xor (str, pass, str):<br><br>';
var sss =  xor(str, pass, 'str');
out.innerHTML += sss;
out.innerHTML += '<br><br>Equal: ' + (str === xor(sss, pass, 'str'));

out.innerHTML += '<hr><br>2.<br> xor (str, pass, []):<br>';
var ssa = xor(str, pass, []);
out.innerHTML += ssa;
out.innerHTML += '<br><br>Equal: ' + (str === xor(ssa, pass, ''));

out.innerHTML += '<hr><br>3.<br> xor (str, p_ar, str):<br>';
var sas =  xor(str, p_ar, 'str');
out.innerHTML += sas;
out.innerHTML += '<br><br>Equal: ' + (str === xor(sas, p_ar, ''));

out.innerHTML += '<hr><br>4.<br> xor (str, p_ar, []):<br>';
var saa =  xor(str, p_ar, []);
out.innerHTML += saa;
out.innerHTML += '<br><br>Equal: ' + (str === xor(saa, p_ar, ''));

//
pitanja_ar = [1,2,3,4,5,6,7,8,9,10];
out.innerHTML += '<hr><br>5.<br> xor([], pass, str)<br>';
var ass = xor(pitanja_ar, pass, '');
out.innerHTML += ass;
var asa = xor(ass, pass, [])
out.innerHTML += '<br><br>Equal: ' + arrays_equal(pitanja_ar,asa);


out.innerHTML += '<hr><br>6.<br> xor([], pass, [])<br>';
var asa = xor(pitanja_ar, pass, []);
out.innerHTML += asa;
out.innerHTML += '<br><br>Equal: ' + arrays_equal(pitanja_ar,xor(asa, pass, []));



out.innerHTML += '<hr><br>7.<br> xor([], p_ar, str)<br>';
var aas =  xor(pitanja_ar, p_ar, '');
out.innerHTML += aas;
out.innerHTML += '<br><br>Equal: ' + arrays_equal(pitanja_ar, xor(aas, p_ar, []));


out.innerHTML += '<hr><br>8.<br> xor([], p_ar, [])<br>';
var aaa =  xor(pitanja_ar, p_ar, []);
out.innerHTML += aaa;
out.innerHTML += '<br><br>Equal: ' + arrays_equal(pitanja_ar, xor(aaa, p_ar, []));

//
share|improve this question
 
Don't overload functions so horribly. An xor for only Strings would have been enough –  copy May 4 '13 at 11:52
 
1. What is horrible and why? 2. Returning a string is optional, returning an array is a must. There are many non printable chars! Number array is copy/paste friendly. –  CoR May 4 '13 at 13:09
 
Writing functions that take many different types as its arguments is horrible. Just see how simple your function could be written if it only accepted Strings. Copy-paste friendlyness is hardly an argument for anything. –  copy May 4 '13 at 15:00
 
Hmmm... If you xor one number (^) with other number, result may be below printable characters on screen. So if copy/paste is not working, you will simply loose data. Only stringified arrays can survive copy/paste. For ex. how do you print \0 or eof on screen? :) But character '0' in array is ok. –  CoR May 4 '13 at 17:44
 
Note that Strings can contain non-printable characters using Unicode escape sequences like \u0008. –  Quentin Pradet May 14 '13 at 7:27
show 1 more comment

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.