diff --git a/01-rozwiazanie.js b/01-rozwiazanie.js new file mode 100644 index 0000000..a42a32f --- /dev/null +++ b/01-rozwiazanie.js @@ -0,0 +1,87 @@ +const rl = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}); + +//zapytanie o wartosc n +rl.question('n? ', n => { + n = parseInt(n); + //sprawdzenie czy n na pewno jest liczba + if (isNaN(n)) throw Error('Must be Number'); + // deklarowanie slownikow dla poszczegolnych elementow(aby się nie powtorzyly) + let elOdw = new Dictionary(); + let dzielZero = new Dictionary(); + let elNil = new Dictionary(); + let elIden = new Dictionary(); + //#region dodanie trywalnych + dzielZero.add(0, 0); + elNil.add(0, 0); + elIden.add(0, 0); + //#endregion + for (let y = 0; y < n; y++) { + //#region Obliczanie elementow Idenpotetnych + if (Math.pow(y, 2) % n == y) { + elIden.add(y, y); + } + //#endregion + for (let x = 0; x < n; x++) { + //#region obliczanie elementow Nilpotetnych + if (Math.pow(y, x) % n == 0) { + elNil.add(y, y); + } + //#endregion + //#region Obliczanie elementow odwracalnych' + if (x >= y && (x * y) % n == 1) { + elOdw.add(x, x); + elOdw.add(y, y); + } + //#endregion + //#region obliczanie dzielnikow zera + if (x >= y && x != 0 && y != 0 && (x * y) % n == 0) { + dzielZero.add(x, x); + dzielZero.add(y, y); + } + //#endregion + } + } + //wypisanie obliczonych wartosci wartosci + console.log([ + elOdw.getValues(), + dzielZero.getValues(), + elNil.getValues(), + elIden.getValues() + ]); + //zamkniecie połaczenia z input/output + rl.close(); +}); + +function NWD(a, b) { + return b ? NWD(b, a % b) : a; +} +// klasa słownika +class Dictionary { + constructor() { + this.elements = {}; + } + add(key, value) { + this.elements[key] = value; + } + remove(key, value) { + delete this.elements[key]; + } + + getKeys() { + let keys = []; + for (let key in this.elements) { + keys.push(key); + } + return keys; + } + getValues() { + let values = []; + for (let key in this.elements) { + values.push(this.elements[key]); + } + return values; + } +} diff --git a/02-rozwiazanie.js b/02-rozwiazanie.js new file mode 100644 index 0000000..93836f2 --- /dev/null +++ b/02-rozwiazanie.js @@ -0,0 +1,22 @@ +let Polynomial = require('./polynomial.js'); +let mul, div, gcd; + + +let n = parseInt(process.argv[2]); +let p1 = JSON.parse(process.argv[3].replace(/'/g, '"')); +let p2 = JSON.parse(process.argv[4].replace(/'/g, '"')); + +let f = new Polynomial.Class(n, p1); +let g = new Polynomial.Class(n, p2); +mul = Polynomial.multiply(f, g).coefficients; +try { + div = Polynomial.divide(f, g).coefficients +} catch (e) { + console.log(e) +} +try { + gcd = Polynomial.gcd(f, g).coefficients; +} catch (e) { + console.log(e); +} +console.log([mul, div, gcd]) \ No newline at end of file diff --git a/03-rozwiazanie.js b/03-rozwiazanie.js new file mode 100644 index 0000000..23fdf1a --- /dev/null +++ b/03-rozwiazanie.js @@ -0,0 +1,20 @@ +const crc = require("./crc.js"); +const message = process.argv[3]; +const flag = process.argv[2]; + +switch (flag) { + case '-e': + console.log(crc.encode(message).encoded); + break; + case '-d': + let fcs = JSON.parse(process.argv[4].replace(/'/g, '"')); + console.log(crc.decode(message, fcs)); + break; + case '-t': + let res = crc.encode(message); + console.log(res.encoded); + console.log(crc.decode(message, res.FCS)) + break; + default: + throw "incorect flag" +} \ No newline at end of file diff --git a/crc.js b/crc.js new file mode 100644 index 0000000..75a90ce --- /dev/null +++ b/crc.js @@ -0,0 +1,117 @@ +const Polynomial = require('./polynomial.js'); + +const L = new Polynomial.Class(2, new Array(16).fill(1)); +const X16 = new Polynomial.Class(2, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); //jako ze można to od razu wymnożyć +const G = new Polynomial.Class(2, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1]); //jako ze można to od razu wymnożyć + +const to_bin = a => { + var result = ""; + for (var i = 0; i < a.length; i++) { + var bin = a[i].charCodeAt().toString(2); + result += Array(8 - bin.length + 1).join("0") + bin; + } + return result; +} +const to_ascii = a => { + a = a.join(''); + a = parseInt(a, 2); + //nie znalazłem innego sposobu w js na osiągniecie tego efektu.. + // if (a < 126) //ponieważ wieksze liczby nie należą do typowego Ascii//porzucone ze wzgledu na decode + return String.fromCharCode(a); + // else { + // return "0x" + a.toString(16); + // // return "\\x" + a.toString(16); //escape \ nie wiem czemu dobrze nie działą i i tak wypisuje \\ + // } + + +} +const mod8format = array => { + while (array.length % 8 != 0) { + array.push(0); + } + return array; +} + +const fcs = m => { + let bits = m.map(to_bin); //message in binary + bits = bits.join('').split('').reverse(); //reverse binary decoded message + let M = new Polynomial.Class(2, bits); + let fcs = Polynomial.multiply(X16, M); + + fcs = Polynomial.add(fcs, + Polynomial.multiply( + Polynomial.Mono(m.length * 8, 1, 2), + L + ) + ) + fcs = Polynomial.divide(fcs, G); + for (let i = 0; i < 16 - fcs.coefficients.length; i++) fcs.coefficients.push(0); + fcs.coefficients.reverse(); + return fcs.coefficients; +} + + + +const check = m => { + + let bits = m.map(to_bin); //message in binary + bits = bits.join('').split('').reverse(); //reverse binary decoded message + + let fcs = Polynomial.Mono(bits.length, 1, 2); + + + let C = new Polynomial.Class(2, bits); + C = Polynomial.multiply(X16, C); + C.coefficients = mod8format(C.coefficients); + let S = Polynomial.add( + C, + Polynomial.multiply( + fcs, + L + ) + ) + + S = Polynomial.divide(S, G) + if (S.coefficients.length === 0) { + return true; + } else + return false; +} + +function encode(m) { + m = m.split(''); + let res = fcs(m); + + let f1 = []; + let f2 = []; + for (let i = 0; i < res.length; i++) { + if (i < 8) { + f1.push(res[i]); + } else { + f2.push(res[i]); + } + } + f1 = to_ascii(f1); + f2 = to_ascii(f2); + m.push(f1); + m.push(f2); + return { + encoded: m, + FCS: [f1, f2] + + }; + +} + +exports.encode = encode; + +function decode(m, fcs) { + m = m.split(''); + to_check = fcs; + for (let char in fcs) { + m.push(fcs[char]); + } + return check(m) + +} +exports.decode = decode; \ No newline at end of file diff --git a/polynomial.js b/polynomial.js new file mode 100644 index 0000000..70626b6 --- /dev/null +++ b/polynomial.js @@ -0,0 +1,180 @@ +class Polynomial { + constructor(mod, coefArray) { + this.mod = mod; + this.degree = (coefArray.length - 1); + + this.coefficients = Array.from(coefArray); //zeby nie przekazywać referencji + this.normalize(); + } + normalize() { + while (this.coefficients && this.coefficients[this.coefficients.length - 1] == 0) { + this.coefficients.pop(); + } + } +} + +exports.Class = Polynomial; + +function get_mod(p1, p2) { + let n; + if (p1.mod !== p2.mod) { + throw "different modulo" + } else { + return p1.mod; + } +} + +function prepare(p1, p2) { + let n = get_mod(p1, p2); + let len_p1 = p1.coefficients.length; + let len_p2 = p2.coefficients.length; + result = new Array(Math.max(len_p1, len_p2)).fill(0); + if (len_p1 > len_p2) { + for (let x = 0; x < len_p1 - len_p2; x++) p2.coefficients.push(0); + } else { + for (let x = 0; x < len_p2 - len_p1; x++) p1.coefficients.push(0); + } + return { + result, + n + }; + +} + +function add(p1, p2) { + + let { + result, + n + } = prepare(p1, p2); + for (let i = 0; i < result.length; i++) { + result[i] = (p1.coefficients[i] + p2.coefficients[i]) % n; + } + return new Polynomial(n, result); +} +exports.add = add; + +function sub(p1, p2) { + let { + result, + n + } = prepare(p1, p2); + for (let i = 0; i < result.length; i++) { + result[i] = (p1.coefficients[i] - p2.coefficients[i]) % n; + } + return new Polynomial(n, result); +} +exports.sub = sub; + +function sub(p1, p2) { + let n = get_mod(p1, p2); + let len_p1 = p1.coefficients.length; + let len_p2 = p2.coefficients.length; + result = new Array(Math.max(len_p1, len_p2)).fill(0); + if (len_p1 > len_p2) { + for (let x = 0; x < len_p1 - len_p2; x++) p2.coefficients.push(0); + } else { + for (let x = 0; x < len_p2 - len_p1; x++) p1.coefficients.push(0); + } + for (let i = 0; i < result.length; i++) { + result[i] = (p1.coefficients[i] - p2.coefficients[i]) % n; + } + return new Polynomial(n, result); +} +exports.add = add; + +function multiply(p1, p2) { + let n = get_mod(p1, p2); + let f = p1.coefficients; + let g = p2.coefficients; + result = new Array(f.length + g.length - 1).fill(0); + + let tmp = []; + for (let i = 0; i < f.length; i++) { + for (let j = 0; j < g.length; j++) { + result[i + j] += f[i] * g[j]; + } + } + return new Polynomial(n, result.map(x => (x % n) + (x < 0 ? n : 0))); +} +exports.multiply = multiply; + +function power(p1, pow) { + let result = p1; + for (let i = 1; i < pow; i++) { + result = multiply(result, p1); + } + return result; +} +exports.power = power; + +function divide(p1, p2) { + let n; + if (p1.mod !== p2.mod) { + throw "different modulo" + } else { + n = p1.mod; + } + let inverse = (x) => { + for (let i = 1; i < 2; i++) { + let r = (i * x) % 2; + if (r == 1) + return i + else + throw "divisionError" + + } + } + if (p1.degree < p2.degree) + return p1; + let f = p1.coefficients; + let g = p2.coefficients; + let g_lead_coef = g[g.length - 1]; + let g_deg = p2.degree; + + while (f.length >= g.length) { + + let f_lead_coef = f[f.length - 1]; + let tmp_coef = f_lead_coef * inverse(g_lead_coef); + let tmp_exp = f.length - 1 - g_deg; + let tmp = []; + for (let i = 0; i < tmp_exp; i++) { + tmp.push(0); + } + tmp.push(tmp_coef); + tmp_poly = new Polynomial(n, tmp); + let sub = multiply(p2, tmp_poly, n); + let tmp_f = []; + for (let i = 0; i < f.length; i++) { + for (let j = 0; j < sub.coefficients.length; j++) { + if (i == j) + tmp_f.push(f[i] - sub.coefficients[j]); + } + } + + f = tmp_f.map(x => (x % n) + (x < 0 ? n : 0)); + while (f && f[f.length - 1] === 0) + f.pop(); + + } + return new Polynomial(n, f); +} + +exports.divide = divide; + +function gcd(p1, p2) { + if (p2.coefficients.length === 0) { + return p1; + } + return gcd(p2, divide(p1, p2)); +} + + +exports.gcd = gcd; + +function Mono(n, c, mod) { + let coef = new Array(n).fill(0); + coef.push(c); + return new Polynomial(mod, coef); +} +exports.Mono = Mono; \ No newline at end of file