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
15 changed files with 444 additions and 53 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));
}
}
}

View File

@ -4,12 +4,10 @@ Napisać program, który dla wiadomości `M` w formie tekstowej ASCII (tj. `8` b
1. utworzy FCS (*Frame Check Sequence*) długości `16` bitów zgodnie z algorytmem **D-1.1**; 1. utworzy FCS (*Frame Check Sequence*) długości `16` bitów zgodnie z algorytmem **D-1.1**;
- INPUT: `M` - tablica znaków ASCII długości `n-2`; - INPUT: `M` - tablica znaków ASCII długości `n-2`;
- OUTPUT: `N` - tablica 8-bitowych liczb (`unsigned char`) długości `n`, która zawiera oryginalną wiadomość `M` na pierwszych `n-2` miejscach, zaś ostatnie dwa zawierają FCS. - OUTPUT: `N` - tablica znaków ASCII długości `n`, która zawiera oryginalną wiadomość `M` na pierwszych `n-2` miejscach, zaś ostatnie zawierają FCS interpretowanymi jako dwa znaki (po 8 bitów każdy).
2. pozwoli sprawdzić, czy dana ramka (tj. wiadomość + FCS) zawiera poprawną treść (zgodnie z **D-1.2**; 2. pozwoli sprawdzić, czy dana ramka (tj. wiadomość + FCS) zawiera poprawną treść (zgodnie z **D-1.2**;
- INPUT: `N` - tablica 8-bitowych liczb (`unsigned char`) długości `n` (np. w formacie hex) - INPUT: `N` - tablica znaków ASCII długości `n`
- OUTPUT: `true` jeśli dwie ostatnie liczby tablicy `N` odpowiadają FCS wiadomości `M = N[0:n-2]` (interpretowanej jako tablica typu `char`), `false` w przeciwnym wypadku; - OUTPUT: `true` jeśli dwa ostatnie znaki `N` odpowiadają FCS wiadomości `M = N[0:n-2]`, `false` w przeciwnym wypadku;
UWAGA: Program w punkcie **2** powinien być w stanie zweryfikować output z punktu **1**!
Źródło: [Report: Telemetry Summary of Concept and Rationale](http://mtc-m16c.sid.inpe.br/col/sid.inpe.br/mtc-m18@80/2009/07.15.17.25/doc/CCSDS%20100.0-G-1.pdf), CCSDS 100.0-G-1 Report Concerning Space. Źródło: [Report: Telemetry Summary of Concept and Rationale](http://mtc-m16c.sid.inpe.br/col/sid.inpe.br/mtc-m18@80/2009/07.15.17.25/doc/CCSDS%20100.0-G-1.pdf), CCSDS 100.0-G-1 Report Concerning Space.

View File

@ -1,48 +0,0 @@
## Zadanie
Napisać program, który dla pierścienia `/n[x]/(f = a₀ + a₁x¹+ ...+ aₖxᵏ)` znajdzie wszystkie
1. elementy odwracalne,
2. dzielniki zera,
3. elementy nilpotentne,
4. elementy idempotentne.
- INPUT: `n [a₀,a₁,...,aₖ]`
- OUTPUT: lista zawierająca cztery powyższe listy elementów (wielomianów, podanych jako listy współczynników)
### Przykłady:
1. `/2[x]/(x² + x + 1)`, który jest ciałem, tzn. `0` jest jedynym elementem nilpotentnym i jedynym dzielnikiem zera:
* INPUT: `2 [1,1,1]`
* OUTPUT:
```shell
[
[[1], [0,1], [0,1], [1,1]], # odwracalne
[[0]], # dzielniki zera
[[0]], # nilpotenty
[[1]] # idempotenty
]
```
1. `/5[x]/(2x³ + 2x² + x + 1)`
* INPUT: `3, [1,1,2,2]`
* OUTPUT:
```sh
[
[[1], [2], [0, 1], [0, 2], [0, 0, 1], [1, 0, 1], [2, 1, 1], [2, 2, 1], [0, 0, 2], [2, 0, 2], [1, 1, 2], [1, 2, 2]], # odwracalne
[[0], [1, 1], [2, 1], [1, 2], [2, 2], [2, 0, 1], [0, 1, 1], [1, 1, 1], [0, 2, 1], [1, 2, 1], [1, 0, 2], [0, 1, 2], [2, 1, 2], [0, 2, 2], [2, 2, 2]], # dzielniki zera
[[0], [2, 0, 1], [1, 0, 2]], # nilpotenty
[[0], [1], [1, 2, 1], [0, 1, 2]] # idempotenty
]
```
### Warunki punktacji
* program musi być typu wsadowego, tj. uruchamiany z linii komend;
* program musi się działać (i kompilować) na serwerze [LTS](https://laboratoria.wmi.amu.edu.pl/en/uslugi/serwer-terminalowy/lts)
UWAGA: **NIE** przyjmuję squashed pulls (z jednym commitem)
### Termin
28.06.2018

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));
}
}