Coverage

100%
100
100
0

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

100%
100
100
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// ----- unit conversion
15// ---------------------------------------
161binary.toInt = function(str) {
174 return parseInt(str, 2);
18};
19
201binary.toHex = function(str) {
212 return parseInt(str, 2).toString(16);
22};
23
24
25// @param n {Number | String | Buffer} input
26// @return {String} 8bit binary conversion
27// todo: get more test cases & verify
281binary.toBinary = function(n) {
29
305 var type = Object.prototype.toString.call(n)
31
325 switch (type) {
33
34 case '[object Number]':
352 return n.toString(2);
36
37 default: // strings and buffers
38
393 var output = '';
40
413 for (var i = 0; i < n.length; i++) {
42
438 var cur = typeof n[i] === 'number' ?
44 binary.pad(n[i].toString(2), 8) // buffers
45 : binary.pad(n.charCodeAt(i).toString(2), 8); // strings
46
478 output += cur;
48
49 }
50
513 return output;
52
53 }
54
55};
56
57
58// ----- arithmetic
59// ---------------------------------------
60
61// @param a {String} binary number
62// @param b {String} binary number
63// todo: @param n {Number} optional bitLength restriction
641binary.add = function(a, b) {
656 a = parseInt(a, 2);
666 b = parseInt(b, 2);
676 return (a + b).toString(2);
68};
69
701binary.addBits = function(a, b) {
714 a = a === '1' ? 1 : 0;
724 b = b === '1' ? 1 : 0;
73
744 var sum = a ^ b;
754 var carry = a & b;
76
774 return {
78 sum: sum.toString(),
79 carry: carry.toString()
80 };
81};
82
83// @param a {String} binary number
84// @param b {String} binary number
85// todo: @param n {Number} optional bitLength restriction
861binary.multiply = function(a, b) {
876 a = parseInt(a, 2);
886 b = parseInt(b, 2);
896 return (a * b).toString(2);
90};
91
92// @param a {String} binary number
93// @param b {String} binary number
94// todo: @param n {Number} optional bitLength restriction
951binary.divide = function(a, b) {
966 a = parseInt(a, 2);
976 b = parseInt(b, 2);
986 return (a / b).toString(2);
99};
100
101
102// ----- logic
103// ---------------------------------------
1041binary.not = function(str) {
10513 var inverse = '';
10613 for (var i = 0; i < str.length; i++) {
10779 inverse += str[i] === '1' ? '0' : '1';
108 }
10913 return inverse;
110};
111
1121binary.and = function(a, b) {
113
1147 var eq = binary.equalize(a, b);
1157 a = eq[0];
1167 b = eq[1];
117
1187 var result = '';
119
1207 for (var i = 0; i < a.length; i++) {
12128 if (a[i] === b[i]) {
1226 result += a[i];
123 }
124 else {
12522 result += '0';
126 }
127 }
128
1297 return result;
130
131};
132
1331binary.or = function(a, b) {
134
1358 var eq = binary.equalize(a, b);
1368 a = eq[0];
1378 b = eq[1];
138
1398 var result = '';
140
1418 for (var i = 0; i < a.length; i++) {
14232 if (a[i] === '1' || b[i] === '1') {
14330 result += '1';
144 }
145 else {
1462 result += '0';
147 }
148 }
149
1508 return result;
151
152};
153
1541binary.nand = function(a, b) {
1553 var and = binary.and(a, b);
1563 return binary.not(and);
157};
158
1591binary.nor = function(a, b) {
1604 var or = binary.or(a, b);
1614 return binary.not(or);
162};
163
1641binary.xor = function(a, b) {
165
1664 var eq = binary.equalize(a, b);
1674 a = eq[0];
1684 b = eq[1];
169
1704 var result = '';
171
1724 for (var i = 0; i < a.length; i++) {
17316 if (a[i] !== b[i]) {
17413 result += '1';
175 }
176 else {
1773 result += '0';
178 }
179 }
180
1814 return result;
182
183};
184
1851binary.complement = function(str) {
1864 var inverse = binary.not(str);
1874 var complement = binary.add(inverse, 1);
1884 return binary.pad(complement, str.length);
189};
190
191
192// ----- etc
193// ---------------------------------------
194
195// @param str {String} binary string
196// @param n {Number} length of output
197// @return {String} left-padded binary string
1981binary.pad = function(str, n) {
19926 while (str.length < n) {
20045 str = '0' + str;
201 }
20226 return str;
203};
204
205// @param str {String} binary string
206// @param n {Number} length of output
207// @param fn {Function} callback
208// @return {Function} callback(err, result)
2091binary.padSafe = function(str, n, fn) {
210
2112 while (str.length < n) {
2124 str = '0' + str;
213 }
214
2152 if (str.length > n) {
2161 var err = new Error('input length exceeds expected length of output');
2171 return fn(err, str);
218 }
219
2201 return fn(null, str);
221
222};
223
224// @param a {String} binary string
225// @param b {String} binary string
226// @return {Array} [(padded) a, (padded) b]
2271binary.equalize = function(a, b) {
228
22921 var aLen = a.length;
23021 var bLen = b.length;
231
23221 if (aLen > bLen) {
2331 b = binary.pad(b, aLen);
234 }
235
23621 if (bLen > aLen) {
23710 a = binary.pad(a, bLen);
238 }
239
24021 return [a, b];
241
242};
243
244// @param str {String} binary string
245// @param length {Number} number of characters per chunk
246// @return {Array}
2471binary.split = function(str, length) {
2482 var regex = new RegExp('.{1,' + length + '}', 'g'); // /.{1,8}/g
2492 return str.match(regex);
250};