Compare commits

...

8 Commits

Author SHA1 Message Date
Hubert Tylkowski
8175042b4a changed error handling 2018-06-27 11:16:10 +02:00
Hubert Tylkowski
7522756ff9 class added 2018-06-25 19:27:24 +02:00
Hubert Tylkowski
744f9793c5 small code refactor 2018-06-20 01:13:23 +02:00
Hubert Tylkowski
446d5f2306 decode added! 2018-06-20 01:06:07 +02:00
Hubert Tylkowski
84c7c81153 encode added! 2018-06-20 00:30:21 +02:00
Hubert Tylkowski
59cc5a61df poly generating & swapping 2018-06-19 00:45:51 +02:00
Hubert Tylkowski
966b225ba8 project started 2018-06-19 00:04:34 +02:00
Hubert Tylkowski
4c976710f9 Zadanie 02 2018-06-09 14:04:27 +02:00
13 changed files with 441 additions and 0 deletions

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,5 @@
public class DivisionErrorException extends Throwable {
public DivisionErrorException() {
System.out.println("Division error!");
}
}

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: Main

View File

@ -0,0 +1,23 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args){
int n = Integer.parseInt(args[0]);
List<Integer> firstPolynomial = new ArrayList<>();
args[1] = args[1].substring(1, args[1].length()-1);
args[2] = args[2].substring(1, args[2].length()-1);
Arrays.asList(args[1].split( ",\\s*" )).forEach(factor -> firstPolynomial.add(Integer.valueOf(factor)));
List<Integer> secondPolynomial = new ArrayList<>();
Arrays.asList(args[2].split(",\\s*" )).forEach(factor -> secondPolynomial.add(Integer.valueOf(factor)));
PolynomialTask polynomialTask = new PolynomialTask(n, firstPolynomial, secondPolynomial);
System.out.print("[");
System.out.print(polynomialTask.printMultipliedPoly()
+ ", " + polynomialTask.printSubtractedPoly()
+ ", " + polynomialTask.printGcd());
System.out.print("]");
}
}

View File

@ -0,0 +1,5 @@
public class MultiplierNotFoundException extends Throwable {
public MultiplierNotFoundException() {
System.out.println("DivisionError");
}
}

View File

@ -0,0 +1,150 @@
import java.util.Arrays;
import java.util.List;
public class PolynomialTask {
private int n;
private int[] firstPolynomialAsArray;
private int[] secondPolynomialAsArray;
public PolynomialTask(int n, List<Integer> firstPoly, List<Integer> secondPoly) {
this.n = n;
this.firstPolynomialAsArray = parseListToArray(firstPoly);
this.secondPolynomialAsArray = parseListToArray(secondPoly);
}
private int[] parseListToArray(List<Integer> polynomial) {
int[] result = new int[polynomial.size()];
for (int i = 0; i < polynomial.size(); i++) {
result[i] = polynomial.get(i);
}
return result;
}
private int[] multiplyPolynomials(int[] firstPolynomial, int[] secondPolynomial) {
int[] multiplied = new int[firstPolynomial.length + secondPolynomial.length - 1];
int sizeOfFirstPoly = firstPolynomial.length;
int sizeOfSecondPoly = secondPolynomial.length;
for (int i = 0; i < sizeOfFirstPoly; i++) {
for (int j = 0; j < sizeOfSecondPoly; j++)
multiplied[i + j] = (multiplied[i + j] + (firstPolynomial[i] * secondPolynomial[j])) % n;
}
return multiplied;
}
private int[] polyDiv(int[] polyOne, int[] polyTwo) {
if (polyOne.length < polyTwo.length) {
return null;
}
int firstPolyDeg = polyOne.length - 1;
int secondPolyDeg = polyTwo.length - 1;
int[] tempArr = new int[polyOne.length];
int[] result;
fillTemporaryArray(polyTwo, tempArr);
int tempMultiplier;
int shift = 0;
while (firstPolyDeg >= secondPolyDeg) {
parseNegativeElement(polyOne, firstPolyDeg);
tempMultiplier = findMultiplier(polyOne[firstPolyDeg], polyTwo[secondPolyDeg]);
tempArr = shiftValuesInArray(tempArr, shift);
tempArr = multiplyPolyByNumber(tempArr, tempMultiplier);
tempArr = moduloArray(tempArr);
polyOne = subtractTwoPolynomials(polyOne, tempArr);
firstPolyDeg--;
shift++;
}
result = Arrays.copyOf(polyOne, shift - 1);
return result;
}
private void fillTemporaryArray(int[] polyTwo, int[] tempArr) {
for (int i = 0; i < polyTwo.length; i++) {
tempArr[tempArr.length - 1 - i] = polyTwo[polyTwo.length - 1 - i];
}
}
private int[] subtractTwoPolynomials(int[] polyOne, int[] polyTwo) {
int[] result = new int[polyOne.length];
for (int i = 0; i < polyOne.length; i++) {
result[i] = polyOne[i] - polyTwo[i];
}
return result;
}
private int[] moduloArray(int[] array) {
for (int i = 0; i < array.length; i++) {
array[i] = array[i] % n;
}
return array;
}
private int[] multiplyPolyByNumber(int[] poly, int multiplier) {
for (int i = 0; i < poly.length; i++) {
poly[i] = poly[i] * multiplier;
}
return poly;
}
private int[] shiftValuesInArray(int[] array, int amount) {
if (amount == 0) {
return array;
} else {
int[] res = new int[array.length];
System.arraycopy(array, amount, res, 0, array.length - amount);
for (int j = array.length - amount + 1; j < res.length; j++) {
res[j] = 0;
}
return res;
}
}
private void parseNegativeElement(int[] polyOne, int firstPolyDeg) {
while (polyOne[firstPolyDeg] < 0) {
polyOne[firstPolyDeg] = n + polyOne[firstPolyDeg];
}
}
private int findMultiplier(int a, int b) {
for (int i = 0; i < n; i++) {
if (a == (b * i) % n) {
return i;
}
}
return -1;
}
public String printMultipliedPoly() {
return Arrays.toString(multiplyPolynomials(firstPolynomialAsArray, secondPolynomialAsArray));
}
public String printSubtractedPoly() {
int[] result = polyDiv(firstPolynomialAsArray, secondPolynomialAsArray);
if (result == null) {
return "Division Error";
} else if (result.length == 0) {
return "[0]";
} else {
return Arrays.toString(polyDiv(firstPolynomialAsArray, secondPolynomialAsArray));
}
}
public String printGcd() {
int[] gcd = gcd(firstPolynomialAsArray, secondPolynomialAsArray);
if (gcd == null) {
return "Division Error";
} else
return Arrays.toString(gcd);
}
private int[] gcd(int[] firstPoly, int[] secondPoly) {
if (secondPoly.length == 0) {
return firstPoly;
}
if (firstPoly.length >= secondPoly.length) {
return gcd(secondPoly, polyDiv(firstPoly, secondPoly));
} else {
return gcd(secondPoly, polyDiv(secondPoly, firstPoly));
}
}
}

6
Zadanie-03/.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

12
Zadanie-03/Zadanie-03.iml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,222 @@
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, String rawMessage) {
this.message = formatMessage(toBinary(message)) + "0000000000000000";
this.rawMessage = rawMessage;
createGeneratingPolynomial();
}
private String toBinary(String s) {
byte[] bytes = s.getBytes();
StringBuilder binary = new StringBuilder();
for (byte b : bytes) {
int val = b;
for (int i = 0; i < 8; i++) {
binary.append((val & 128) == 0 ? 0 : 1);
val <<= 1;
}
}
return binary.toString();
}
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;
}
}
for (int i = firstNonZeroVal; i < message.length(); i++) {
if (message.charAt(i) == 48) {
validString.append(0);
} else {
validString.append(1);
}
}
StringBuilder msg = new StringBuilder(validString.toString());
while (msg.length() % 8 != 0) {
msg.insert(0, "0");
}
return msg.toString();
}
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 "" + getCharFromShortArray(piece, 0, 8) + getCharFromShortArray(piece, piece.length - 8, piece.length);
}
short[] remainder = calcXOR(piece, polyGenerator);
remainder = removeUnecessaryZeros(remainder);
messageAsShortArray = createMessageFromRemainderAndPartFromOldMessage(remainder, messageAsShortArray);
}
}
}
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[] chunk, short[] polyGenerator) {
int a = Integer.parseInt(shortArrayToBinaryString(chunk), 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 char getCharFromShortArray(short[] chunk, int from, int to) {
short[] sign = Arrays.copyOfRange(chunk, from, to);
int character = Integer.parseInt(shortArrayToBinaryString(sign), 2);
// System.out.println(character);
return (char) character;
}
private void fillPolynomial(short[] chunk) {
while (chunk.length % 8 != 0) {
chunk = addZeroAtBeginningOfArray(chunk);
}
}
private short[] addZeroAtBeginningOfArray(short[] chunk) {
short[] letterTemp = new short[chunk.length + 1];
letterTemp[0] = 0;
System.arraycopy(chunk, 0, letterTemp, 1, chunk.length);
return letterTemp;
}
private void convertMessageToBinaryShortArray() {
messageAsShortArray = new short[message.length()];
for (int i = 0; i < polyGenerator.length; i++) {
if (message.charAt(i) == 48) {
messageAsShortArray[i] = 0;
} else {
messageAsShortArray[i] = 1;
}
}
}
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() {
convertMessageToBinaryShortArray();
messageAsShortArray = swapPolynomialValues(messageAsShortArray);
return rawMessage + generateFCS();
}
boolean decode(String encodedString) {
encodedString = toBinary(encodedString);
encodedString = fillPolyTo8(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 boolean shortArrayContains(short[] encodedShortArray, int value) {
for (short item : encodedShortArray) {
if (item == value) {
return true;
}
}
return false;
}
private String fillPolyTo8(String encodedString) {
StringBuilder stringBuilder = new StringBuilder(encodedString);
while (stringBuilder.length() % 8 != 0) {
stringBuilder.insert(0, "0");
}
return stringBuilder.toString();
}
}

View File

@ -0,0 +1,15 @@
package com.tylkowski.crc;
public class Main {
public static void main(String[] args) {
// ex. in command line type "a"
CrcTask crcTask = new CrcTask(args[0], args[0]);
System.out.println(crcTask.encode());
String input = crcTask.encode();
if (input.length() >= 3) System.out.println(crcTask.decode(input));
}
}