forked from kalmar/DALGLI0
program now using polyomial class to calculate FCS
This commit is contained in:
parent
2e16ad8b73
commit
446a46fd69
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
182
Zadanie-03/src/com/tylkowski/crc/Polynomial.java
Normal file
182
Zadanie-03/src/com/tylkowski/crc/Polynomial.java
Normal file
@ -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<Integer> 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<Integer> 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<Integer> 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<Integer> asList() {
|
||||
return Arrays.stream(polynomial).boxed().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public ArrayList<Integer> asArrayList() {
|
||||
ArrayList<Integer> 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<Integer> 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];
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user