package pl.mkaczara.bch.testbench;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Random;
import pl.mkaczara.bch.code.BCHCode;
/**
* Klasa obiektow reprezentujacych symulatory transmisji danych
*
* @author Kuba
*/
public class TransmissionSimulator {
/**
* Ile bledow wygenerowac?
*/
private int errorsToProvide;
/**
* Rozrzut bledow
*/
private ErrorScope errorsScope;
/**
* Kod przesylanych danych
*/
private BCHCode code;
/**
* Tworzy obiekt symylatora transmisji
*
* @param errorsToProvide liczba bledow do wprowadzenia
* @param code kod przesylanych danych
*/
public TransmissionSimulator(int errorsToProvide, ErrorScope errorRange, BCHCode code) {
this.errorsToProvide = errorsToProvide;
this.errorsScope = errorRange;
this.code = code;
}
/**
* Symuluje przesylanie danych i wprowadza zadana liczbe bledow
*
* @param data dane na wejsciu (przed przeslaniem)
* @return dane po przeslaniu (na wyjsciu)
*/
public byte[] transmitData(byte[] data){
BigInteger bi = new BigInteger(data);
Random randomGenerator = new Random();
int errorPosMin = errorsScope.equals(ErrorScope.CODEWORD_SIZE) ? 0 : (code.getK() < code.getN() / 2 ? code.getK() :code.getN() - code.getK());
int errorPosMax = errorsScope.equals(ErrorScope.CODEWORD_SIZE) ? (code.getN()) : (code.getN() - code.getK());
for(int b = 0; b < bi.bitLength(); b += code.getN()){
int errorStart = (0 == errorPosMin ? errorPosMin : randomGenerator.nextInt(errorPosMin));
//Lista, w celu wyeliminowania powtarzania
ArrayList<Integer> olderPos = new ArrayList<>();
for (int i = 0; i < errorsToProvide; i++) {
int errorPos = randomGenerator.nextInt(errorPosMax) + errorStart + b;
while (olderPos.contains(errorPos)) {
errorPos = randomGenerator.nextInt(errorPosMax) + errorStart + b;
}
//Zamiana bitu
bi = bi.flipBit(errorPos);
olderPos.add(errorPos);
}
olderPos.clear();
}
return bi.toByteArray();
}
/**
* @return zasieg (rozrzut) bledow w slowie kodowym
*/
public ErrorScope getErrorsScope() {
return errorsScope;
}
/**
* @return liczba bledow do wprowadzenia
*/
public int getErrorsToProvide() {
return errorsToProvide;
}
/**
* Zasieg (rozrzut) bledu
*/
public enum ErrorScope {
/**
* Bledy rozrzucone po max. N-K pozycjach
*/
CORRECTION_PART_SIZE,
/**
* Bledy rozrzucone po calym slowie kodowym
*/
CODEWORD_SIZE
}
} // end TransmissionSimulator