diff --git a/Zadanie-03/out/artifacts/Zadanie_03_jar/Zadanie-03.jar b/Zadanie-03/out/artifacts/Zadanie_03_jar/Zadanie-03.jar index 5d76ae0..3c9152a 100644 Binary files a/Zadanie-03/out/artifacts/Zadanie_03_jar/Zadanie-03.jar and b/Zadanie-03/out/artifacts/Zadanie_03_jar/Zadanie-03.jar differ diff --git a/Zadanie-03/out/production/Zadanie-03/com/tylkowski/crc/CrcTask.class b/Zadanie-03/out/production/Zadanie-03/com/tylkowski/crc/CrcTask.class index 13d1da1..1b2277b 100644 Binary files a/Zadanie-03/out/production/Zadanie-03/com/tylkowski/crc/CrcTask.class and b/Zadanie-03/out/production/Zadanie-03/com/tylkowski/crc/CrcTask.class differ diff --git a/Zadanie-03/out/production/Zadanie-03/com/tylkowski/crc/Main.class b/Zadanie-03/out/production/Zadanie-03/com/tylkowski/crc/Main.class index 86a430a..b8e11f9 100644 Binary files a/Zadanie-03/out/production/Zadanie-03/com/tylkowski/crc/Main.class and b/Zadanie-03/out/production/Zadanie-03/com/tylkowski/crc/Main.class differ diff --git a/Zadanie-03/out/production/Zadanie-03/com/tylkowski/crc/Polynomial.class b/Zadanie-03/out/production/Zadanie-03/com/tylkowski/crc/Polynomial.class new file mode 100644 index 0000000..98f1f4f Binary files /dev/null and b/Zadanie-03/out/production/Zadanie-03/com/tylkowski/crc/Polynomial.class differ diff --git a/Zadanie-03/src/com/tylkowski/crc/CrcTask.java b/Zadanie-03/src/com/tylkowski/crc/CrcTask.java index 1b02ada..fb09a25 100644 --- a/Zadanie-03/src/com/tylkowski/crc/CrcTask.java +++ b/Zadanie-03/src/com/tylkowski/crc/CrcTask.java @@ -3,158 +3,46 @@ package com.tylkowski.crc; import java.util.Arrays; class CrcTask { - private String message; - private short[] messageAsShortArray; - private short[] polyGenerator; - private String rawMessage; - - CrcTask(String message) { - this.rawMessage = message; - this.message = formatMessage(toBinaryString(message)) + "0000000000000000"; - createGeneratingPolynomial(); + public CrcTask() { } - - private String formatMessage(String message) { - int firstNonZeroVal = 0; - boolean found = false; - StringBuilder validString = new StringBuilder(); - while (!found && firstNonZeroVal < message.length()) { - if (message.charAt(firstNonZeroVal) == 48) { - firstNonZeroVal++; - } else { - found = true; - } + public Polynomial encode(String message) { + Polynomial g = new Polynomial("[1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1]", 2); //G(X) + Polynomial l = new Polynomial("[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]", 2); // L(X) 16 * 1 + Polynomial m = new Polynomial("[" + formatMessageToBinaryArrayPolynomial(message) + "]", 2); + m.reverse(); + Polynomial tmp2 = new Polynomial(l); + for (int i = 0; i < m.getSize(); i++) { + tmp2.append(0, 0); } - - for (int i = firstNonZeroVal; i < message.length(); i++) { - if (message.charAt(i) == 48) { - validString.append(0); - } else { - validString.append(1); - } + Polynomial tmp = new Polynomial(m); + for (int i = 0; i < 16; i++) { + tmp.append(0, 0); } - StringBuilder msg = new StringBuilder(validString.toString()); - while (msg.length() % 8 != 0) { - msg.insert(0, "0"); + Polynomial sum = tmp.add(tmp2); + Polynomial fcsPoly = sum.moduloPolyDivide(g); + while (fcsPoly.getSize() < 16) { + fcsPoly.append(0, 0); } - - return msg.toString(); + fcsPoly.reverse(); + return fcsPoly; } - private String generateFCS() { - while (true) { - if (messageAsShortArray[0] == 0) { - messageAsShortArray = Arrays.copyOfRange(messageAsShortArray, 1, messageAsShortArray.length); - } else { - short[] piece = Arrays.copyOfRange(messageAsShortArray, 0, Math.min(polyGenerator.length, messageAsShortArray.length)); - if (piece.length < polyGenerator.length) { - fillPolynomial(piece); - return createTwoCharsOfFCS(piece); - } - short[] remainder = calcXOR(piece, polyGenerator); - remainder = removeUnecessaryZeros(remainder); - messageAsShortArray = createMessageFromRemainderAndPartFromOldMessage(remainder, messageAsShortArray); - } - } - + public String generateFCSChars(Polynomial poly) { + String binString = Arrays.toString(poly.getPolynomialArray()); + binString = binString.replace(",", ""); + binString = binString.replace("]", ""); + binString = binString.replace("[", ""); + binString = binString.replace(" ", ""); + return "0x" + Integer.toHexString(Integer.parseInt(binString, 2)); } - private String createTwoCharsOfFCS(short[] piece) { - short[] firstPiece = Arrays.copyOfRange(piece, 0, 8); - short[] secondPiece = Arrays.copyOfRange(piece, piece.length - 8, piece.length); - short[] mergedPieces = new short[firstPiece.length + secondPiece.length]; - for (int i = 0; i < firstPiece.length; i++) { - mergedPieces[i] = firstPiece[i]; - mergedPieces[i + 8] = secondPiece[i]; - } - return "0x" + Integer.toHexString(Integer.parseInt(shortArrayToBinaryString(mergedPieces), 2)); - } - - private short[] createMessageFromRemainderAndPartFromOldMessage(short[] remainder, short[] msg) { - short[] tempArr = new short[remainder.length + msg.length - polyGenerator.length]; - System.arraycopy(remainder, 0, tempArr, 0, remainder.length); - int diff = polyGenerator.length - remainder.length; - System.arraycopy(msg, remainder.length + diff, tempArr, remainder.length, msg.length - diff - remainder.length); - msg = tempArr; - return msg; - } - - private short[] removeUnecessaryZeros(short[] remainder) { - int firstNonZeroVal = 0; - boolean found = false; - while (!found && firstNonZeroVal < remainder.length) { - if (remainder[firstNonZeroVal] == 0) { - firstNonZeroVal++; - } else { - found = true; - } - } - return Arrays.copyOfRange(remainder, firstNonZeroVal, remainder.length); - } - - private short[] calcXOR(short[] piece, short[] polyGenerator) { - int a = Integer.parseInt(shortArrayToBinaryString(piece), 2); - int b = Integer.parseInt(shortArrayToBinaryString(polyGenerator), 2); - String binaryString = Integer.toBinaryString(a ^ b); - return convertBinaryStringToShortArray(binaryString); - } - - private String shortArrayToBinaryString(short[] value) { - StringBuilder binaryString = new StringBuilder(); - for (Short a : value) { - binaryString.append(a); - } - return binaryString.toString(); - } - - private void fillPolynomial(short[] piece) { - while (piece.length % 8 != 0) { - piece = addZeroAtBeginningOfArray(piece); - } - } - - private short[] addZeroAtBeginningOfArray(short[] piece) { - short[] tempArray = new short[piece.length + 1]; - tempArray[0] = 0; - System.arraycopy(piece, 0, tempArray, 1, piece.length); - return tempArray; - } - - private short[] convertBinaryStringToShortArray(String binaryString) { - short[] shortArray = new short[binaryString.length()]; - for (int i = 0; i < binaryString.length(); i++) { - if (binaryString.charAt(i) == 48) { - shortArray[i] = 0; - } else { - shortArray[i] = 1; - } - } - return shortArray; - } - - private void createGeneratingPolynomial() { - polyGenerator = new short[17]; - for (int i = 0; i < 17; i++) { - polyGenerator[i] = 0; - } - polyGenerator[0] = 1; - polyGenerator[4] = 1; - polyGenerator[11] = 1; - polyGenerator[16] = 1; - } - - private short[] swapPolynomialValues(short[] poly) { - for (int i = 0; i < polyGenerator.length - 1; i++) { - poly[i] = (short) ((poly[i] + 1) % 2); - } - return poly; - } - - String encode() { - messageAsShortArray = convertBinaryStringToShortArray(message); - messageAsShortArray = swapPolynomialValues(messageAsShortArray); - return rawMessage + generateFCS(); + private String formatMessageToBinaryArrayPolynomial(String message) { + String msgBinString = toBinaryString(message); + msgBinString = msgBinString.replace("1", "1,"); + msgBinString = msgBinString.replace("0", "0,"); + msgBinString = msgBinString.substring(0, msgBinString.length() - 1); + return msgBinString; } private String letterToBinaryString(char letter) { @@ -166,33 +54,6 @@ class CrcTask { return binaryString.toString(); } - boolean decode(String encodedString) { - String fcs = encodedString.substring(encodedString.indexOf("0x"), encodedString.length()); - encodedString = encodedString.replace(fcs, ""); - encodedString = toBinaryString(encodedString); - encodedString = encodedString + toBinaryStringFromHexValue(fcs); - encodedString = fillPoly(encodedString); - short[] encodedShortArray = convertBinaryStringToShortArray(encodedString); - encodedShortArray = swapPolynomialValues(encodedShortArray); - while (true) { - if (!shortArrayContains(encodedShortArray, 1)) { - return true; - } - if (encodedShortArray[0] == 0) { - encodedShortArray = Arrays.copyOfRange(encodedShortArray, 1, encodedShortArray.length); - } else { - short[] piece = Arrays.copyOfRange(encodedShortArray, 0, Math.min(polyGenerator.length, encodedShortArray.length)); - if (piece.length < polyGenerator.length) { - return false; - } - - short[] remainder = calcXOR(piece, polyGenerator); - remainder = removeUnecessaryZeros(remainder); - encodedShortArray = createMessageFromRemainderAndPartFromOldMessage(remainder, encodedShortArray); - } - } - } - private String toBinaryStringFromHexValue(String hexString) { hexString = hexString.substring(2, hexString.length()); return String.valueOf(Integer.toBinaryString(Integer.parseInt(hexString, 16))); @@ -206,20 +67,31 @@ class CrcTask { return stringBuilder.toString(); } - private boolean shortArrayContains(short[] encodedShortArray, int value) { - for (short item : encodedShortArray) { - if (item == value) { - return true; - } + public boolean decode(String messageString) { + Polynomial g = new Polynomial("[1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1]", 2); + Polynomial l = new Polynomial("[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]", 2); + String fcs = messageString.substring(messageString.indexOf("0x"), messageString.length()); + messageString = messageString.replace(fcs, ""); + messageString = toBinaryString(messageString); + String messageAsBinaryString = messageString + toBinaryStringFromHexValue(fcs); + Polynomial message = new Polynomial("[" + toPolynomialStringFromBinaryString(messageAsBinaryString) + "]", 2); + message.reverse(); + for (int i = 0; i < 16; i++) { + message.append(0,0); } - return false; + Polynomial tmp = new Polynomial(l); + for (int i = 0; i < messageAsBinaryString.length(); i++) { + tmp.append(0, 0); + } + Polynomial sum = message.add(tmp); + message = sum.moduloPolyDivide(g); + return message.haveOnlyZeros(); } - private String fillPoly(String encodedString) { - StringBuilder stringBuilder = new StringBuilder(encodedString); - while (stringBuilder.length() % 8 != 0) { - stringBuilder.insert(0, "0"); - } - return stringBuilder.toString(); + private String toPolynomialStringFromBinaryString(String msgBinString) { + msgBinString = msgBinString.replace("1", "1,"); + msgBinString = msgBinString.replace("0", "0,"); + msgBinString = msgBinString.substring(0, msgBinString.length() - 1); + return msgBinString; } } diff --git a/Zadanie-03/src/com/tylkowski/crc/Main.java b/Zadanie-03/src/com/tylkowski/crc/Main.java index 3911551..bb87639 100644 --- a/Zadanie-03/src/com/tylkowski/crc/Main.java +++ b/Zadanie-03/src/com/tylkowski/crc/Main.java @@ -7,13 +7,15 @@ public class Main { // example "1" "b" -> this will encode string "b" and return FCS // example "2" "bX" -> this will decode string "bX" and return true if it is valid or false if not // X - FCS - CrcTask crcTask = new CrcTask(args[1]); + CrcTask crcTask = new CrcTask(); if (args[0].equals("1")) { //create FCS - System.out.println(crcTask.encode()); + System.out.println(args[1] + crcTask.generateFCSChars(crcTask.encode(args[1]))); } else if (args[0].equals("2")) { // check fcs - if (args[1].length() >= 3) System.out.println(crcTask.decode(args[1])); + if (args[1].length() >= 3) { + System.out.println(crcTask.decode(args[1])); + } } } diff --git a/Zadanie-03/src/com/tylkowski/crc/Polynomial.java b/Zadanie-03/src/com/tylkowski/crc/Polynomial.java new file mode 100644 index 0000000..d1de700 --- /dev/null +++ b/Zadanie-03/src/com/tylkowski/crc/Polynomial.java @@ -0,0 +1,182 @@ +package com.tylkowski.crc; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class Polynomial { + private int[] polynomial; + private int modulo; + + public Polynomial(String polyString, int modulo) { + this.polynomial = parsePolynomialString(polyString); + this.modulo = modulo; + } + + public Polynomial(int[] polynomial, int modulo) { + this.polynomial = polynomial; + this.modulo = modulo; + } + + public Polynomial(List polynomial, int modulo) { + this.polynomial = polynomial.stream().mapToInt(i -> i).toArray(); + this.modulo = modulo; + } + + public Polynomial(Polynomial polynomial) { + this.polynomial = polynomial.getPolynomialArray(); + this.modulo = polynomial.getModulo(); + } + + + public void append(int index, int value) { + ArrayList poly = asArrayList(); + poly.add(index, value); + polynomial = poly.stream().mapToInt(i -> i).toArray(); + } + + + private int[] parsePolynomialString(String poly) { + poly = poly.substring(1, poly.length() - 1); + return Arrays.stream(poly.split(",\\s*")).map(String::trim).mapToInt(Integer::parseInt).toArray(); + } + + public int[] getPolynomialArray() { + return polynomial; + } + + + public int getModulo() { + return modulo; + } + + + public Polynomial subtract(Polynomial polyTwo) { + Polynomial polyOne = new Polynomial(this); + ArrayList result = new ArrayList<>(); + for (int i = 0; i < polyOne.getSize(); ++i) { + if (i < polyTwo.getSize()) { + result.add(Math.floorMod(polyOne.coeffAt(i) - polyTwo.coeffAt(i), modulo)); + } else { + result.add(polyOne.coeffAt(i)); + } + } + return new Polynomial(result, modulo); + } + + public int getSize() { + return polynomial.length; + } + + public int coeffAt(int i) { + return polynomial[i]; + } + + public void set(int index, int value) { + polynomial[index] = value; + } + + public List asList() { + return Arrays.stream(polynomial).boxed().collect(Collectors.toList()); + } + + public ArrayList asArrayList() { + ArrayList result = new ArrayList<>(); + for (int i = 0; i < polynomial.length; i++) { + result.add(polynomial[i]); + } + return result; + } + + public Polynomial add(Polynomial polyTwo) { + int size = Math.max(polynomial.length, polyTwo.getSize()); + int[] result = new int[size]; + for (int i = 0; i < size; i++) { + int res = 0; + if (i >= polynomial.length) { + res = polyTwo.coeffAt(i); + } + if (i >= polyTwo.getSize()) { + res = polynomial[i]; + } + if (i < polynomial.length && i < polyTwo.getSize()) { + res = polynomial[i] + polyTwo.coeffAt(i); + } + result[i] = res; + } + Polynomial resultPoly = new Polynomial(result, modulo); + resultPoly = resultPoly.moduloPoly(resultPoly); + return resultPoly; + } + + public Polynomial multiplyByNumber(int a) { + ArrayList result = new ArrayList<>(); + for (int i = 0; i < polynomial.length; i++) { + result.add((polynomial[i] * a) % modulo); + } + return new Polynomial(result, modulo); + } + + public boolean haveOnlyZeros() { + return !asArrayList().contains(1); + } + + public Polynomial moduloPoly(Polynomial poly) { + for (int i = 0; i < poly.getSize(); i++) { + while (poly.coeffAt(i) < 0) { + poly.getPolynomialArray()[i] = poly.getPolynomialArray()[i] + modulo; + } + poly.getPolynomialArray()[i] = poly.getPolynomialArray()[i] % modulo; + } + return poly; + } + + private int findZero(int a, int b, int modulo) { + for (int i = 0; i <= modulo; i++) { + if ((a + (-(b * i))) == 0) { + return i; + } + } + return -1; + } + public Polynomial moduloPolyDivide(Polynomial polyTwo) { + Polynomial polyOne = new Polynomial(this); + Polynomial quotient = new Polynomial("[0]", polyOne.getModulo()); + Polynomial rem = new Polynomial(polyOne); + Polynomial tmpPoly; + int polyOneIterator = polyOne.getSize() - 1; + int polyTwoIterator = polyTwo.getSize() - 1; + for (int i = 0; i < polyOneIterator - polyTwoIterator; i++) { + quotient.append(0, 0); + } + int quotientIterator = quotient.getSize() - 1; + int tmpZero; + while (polyOneIterator >= polyTwoIterator) { + tmpZero = findZero(rem.coeffAt(polyOneIterator), polyTwo.coeffAt(polyTwoIterator), polyOne.getModulo()); + quotient.set(quotientIterator--, tmpZero); + tmpPoly = polyTwo.multiplyByNumber(tmpZero); + while (tmpPoly.getSize() <= polyOneIterator) { + tmpPoly.append(0, 0); + } + rem = rem.subtract(tmpPoly); + polyOneIterator--; + } + return rem; + } + + @Override + public String toString() { + return "Polynomial{" + + "polynomial=" + Arrays.toString(polynomial) + + ", modulo=" + modulo + + '}'; + } + + public void reverse() { + int[] temp = Arrays.copyOf(getPolynomialArray(), getPolynomialArray().length); + for (int i = 0; i < temp.length; i++) { + polynomial[i] = temp[temp.length - i - 1]; + } + } +}