Coverage

100%
117
117
0

/Users/sebastiansandqvist/Documents/Sites & Projects/apps/#modules/s-binary/index.js

100%
117
117
0
LineHitsSource
11'use strict';
2
3// ----------------------------------------------------------------------
4// ----- main exported object
5// includes:
6// 1. unit conversions
7// 2. arithmetic functions
8// 3. logical operators
9// 4. helper methods
10// ----------------------------------------------------------------------
11
121var binary = module.exports = {};
13
14
15// ----- unit conversion
16// ---------------------------------------
171binary.toInt = function(str) {
1810 return parseInt(str, 2);
19};
20
211binary.toHex = function(str) {
222 return parseInt(str, 2).toString(16);
23};
24
25// binary.toBase64 = function(str) {
26// str = parseInt(str, 2).toString();
27// var buf = new Buffer(str);
28// return buf.toString('base64');
29// };
30
31// @param n {Number | String | Buffer} input
32// @return {String} 8bit binary conversion
33// todo: get more test cases & verify
341binary.toBinary = function(n) {
35
366 var type = Object.prototype.toString.call(n);
37
386 if (type === '[object Number]') {
392 return n.toString(2);
40 }
41
424 var output = '';
43
444 for (var i = 0; i < n.length; i++) {
45
4622 var cur = typeof n[i] === 'number' ?
47 binary.pad(n[i].toString(2), 8) // buffers
48 : binary.pad(n.charCodeAt(i).toString(2), 8); // strings
49
5022 output += cur;
51
52 }
53
544 return output;
55
56};
57
58
59// @param str {String} binary string
60// @return {String} Unicode string
611binary.toUnicode = function(str) {
62
632 var arr = binary.split(str);
642 var output = '';
65
662 for (var i=0, len=arr.length; i<len; i++) {
676 var integer = binary.toInt(arr[i]);
686 output += String.fromCharCode(integer);
69 }
70
712 return output;
72
73};
74
75
76// ----- arithmetic
77// ---------------------------------------
78
79// @param a {String} binary number
80// @param b {String} binary number
81// todo: @param n {Number} optional bitLength restriction
821binary.add = function(a, b) {
836 a = parseInt(a, 2);
846 b = parseInt(b, 2);
856 return (a + b).toString(2);
86};
87
881binary.addBits = function(a, b) {
894 a = a === '1' ? 1 : 0;
904 b = b === '1' ? 1 : 0;
91
924 var sum = a ^ b;
934 var carry = a & b;
94
954 return {
96 sum: sum.toString(),
97 carry: carry.toString()
98 };
99};
100
101// @param a {String} binary number
102// @param b {String} binary number
103// todo: @param n {Number} optional bitLength restriction
1041binary.multiply = function(a, b) {
1056 a = parseInt(a, 2);
1066 b = parseInt(b, 2);
1076 return (a * b).toString(2);
108};
109
110// @param a {String} binary number
111// @param b {String} binary number
112// todo: @param n {Number} optional bitLength restriction
1131binary.divide = function(a, b) {
1146 a = parseInt(a, 2);
1156 b = parseInt(b, 2);
1166 return (a / b).toString(2);
117};
118
119
120// ----- logic
121// ---------------------------------------
1221binary.not = function(str) {
12313 var inverse = '';
12413 for (var i = 0; i < str.length; i++) {
12579 inverse += str[i] === '1' ? '0' : '1';
126 }
12713 return inverse;
128};
129
1301binary.and = function(a, b) {
131
1327 var eq = binary.equalize(a, b);
1337 a = eq[0];
1347 b = eq[1];
135
1367 var result = '';
137
1387 for (var i = 0; i < a.length; i++) {
13928 if (a[i] === b[i]) {
1406 result += a[i];
141 }
142 else {
14322 result += '0';
144 }
145 }
146
1477 return result;
148
149};
150
1511binary.or = function(a, b) {
152
1538 var eq = binary.equalize(a, b);
1548 a = eq[0];
1558 b = eq[1];
156
1578 var result = '';
158
1598 for (var i = 0; i < a.length; i++) {
16032 if (a[i] === '1' || b[i] === '1') {
16130 result += '1';
162 }
163 else {
1642 result += '0';
165 }
166 }
167
1688 return result;
169
170};
171
1721binary.nand = function(a, b) {
1733 var and = binary.and(a, b);
1743 return binary.not(and);
175};
176
1771binary.nor = function(a, b) {
1784 var or = binary.or(a, b);
1794 return binary.not(or);
180};
181
1821binary.xor = function(a, b) {
183
1844 var eq = binary.equalize(a, b);
1854 a = eq[0];
1864 b = eq[1];
187
1884 var result = '';
189
1904 for (var i = 0; i < a.length; i++) {
19116 if (a[i] !== b[i]) {
19213 result += '1';
193 }
194 else {
1953 result += '0';
196 }
197 }
198
1994 return result;
200
201};
202
2031binary.complement = function(str) {
2044 var inverse = binary.not(str);
2054 var complement = binary.add(inverse, 1);
2064 return binary.pad(complement, str.length);
207};
208
209
210// ----- etc
211// ---------------------------------------
212
213// @param str {String} binary string
214// @param n {Number} length of output
215// @return {String} left-padded binary string
2161binary.pad = function(str, n) {
21740 while (str.length < n) {
21862 str = '0' + str;
219 }
22040 return str;
221};
222
223// @param str {String} binary string
224// @param n {Number} length of output
225// @param fn {Function} callback
226// @return {Function} callback(err, result)
2271binary.padSafe = function(str, n, fn) {
228
2292 while (str.length < n) {
2304 str = '0' + str;
231 }
232
2332 if (str.length > n) {
2341 var err = new Error('input length exceeds expected length of output');
2351 return fn(err, str);
236 }
237
2381 return fn(null, str);
239
240};
241
242// @param a {String} binary string
243// @param b {String} binary string
244// @return {Array} [(padded) a, (padded) b]
2451binary.equalize = function(a, b) {
246
24721 var aLen = a.length;
24821 var bLen = b.length;
249
25021 if (aLen > bLen) {
2511 b = binary.pad(b, aLen);
252 }
253
25421 if (bLen > aLen) {
25510 a = binary.pad(a, bLen);
256 }
257
25821 return [a, b];
259
260};
261
262// @param str {String} binary string
263// @param length {Number} optional number of characters per chunk; default is 8
264// @return {Array}
2651binary.split = function(str, length) {
2666 if (!length) {
2673 length = 8;
268 }
2696 var regex = new RegExp('.{1,' + length + '}', 'g'); // /.{1,8}/g
2706 return str.match(regex);
271};
272
273// @param arr {Array} array of equal length binary strings
274// @return {String} least significant bits
2751binary.lsb = function(arr) {
276
2771 var output = '';
278
2791 for (var i=0, len=arr.length; i<len; i++) {
28014 var byteLength = arr[i].length;
28114 var bit = arr[i][byteLength - 1];
28214 var out = bit === '0' ? '0' : '1';
28314 output += out;
284 }
285
2861 return output;
287
288};