<commit_before>package org.cipher.ciphtypes.substition.complex;

import org.cipher.ciphtypes.substition.simple.SimpleSubstitutionCipher;

import java.security.InvalidKeyException;
import java.util.*;

/**
 * The Polybius Square is essentially identical to the simple substitution cipher,
 * except that each plaintext character is enciphered as 2 ciphertext characters.
 * It can ususally be detected if there are only 5 or 6 different characters in the
 * ciphertext. This algorithm offers very little communication security, and can be
 * easily broken even by hand, especially as the messages become longer (more than
 * several hundred ciphertext characters).
 *
 * @author Piotr 'pitrecki' Nowak
 * @version 0.0.1
 * @see SimpleSubstitutionCipher
 * Created by Pitrecki on 2016-10-30.
 */
public class PolybiusSquareCipher extends ComplexSubstitutionCipher
{
    //Length ====> 25
    private final int KEY_LENGTH = ASCII_TABLE.length - 1;

    private String cipherKey;

    public PolybiusSquareCipher() {
        super();
        keyGenerator();
        squareGenerator(getCipherKey());
    }

    public PolybiusSquareCipher(String key) throws InvalidKeyException {
        super();
        if (!(key.length() == KEY_LENGTH))
            throw new InvalidKeyException("Invalid cipherKey length: " + key.length() + " expected length: 25");
        else if (!isUnigue(key))
            throw new InvalidKeyException("Invalid cipherKey length, expected length: 25");
        else
            this.cipherKey = key.toUpperCase();
        squareGenerator(getCipherKey());
    }

    public String getCipherKey() {
        return cipherKey;
    }


    private void squareGenerator(String key) {
        Character[][] cryptSqaure = new Character[5][5];
        int index = 0;

        for (int i = 0; i < cryptSqaure.length; i++) {
            for (int j = 0; j < cryptSqaure[i].length; j++) {
                cryptSqaure[i][j] = key.charAt(index++);
            }
        }

        setCryptMatrix(cryptSqaure);

    }

    /**
     * Generate unique key
     * List should  prevent from duplicated values
     */
    private void keyGenerator() {
        StringBuilder builder = new StringBuilder();
        List<Character> list = new ArrayList<>();
        for (char letter : ASCII_TABLE)
            list.add(letter);
        Random random = new Random();
        do {
            int randomizeInteger = random.nextInt(list.size());
            builder.append(list.get(randomizeInteger));
            list.remove(randomizeInteger);

        }
        while (builder.length() <= KEY_LENGTH);

        this.cipherKey = builder.toString();
    }

    /**
     * This method is responosbile for check is typed key by user is unique
     * @param key input key by user
     * @return true if key length is same, Set colection
     */
    private boolean isUnigue(String key) {
        Set<Character> characterSet = new HashSet<>();
        for (char letter : key.toCharArray())
            characterSet.add(letter);

        return key.length() == characterSet.size();
    }

    @Override<commit_msg>refactoring and fixed implementation of key generating in PolybiusSqureCipher.<commit_after>package org.cipher.ciphtypes.substition.complex;

import org.cipher.ciphtypes.substition.simple.SimpleSubstitutionCipher;

import java.security.InvalidKeyException;
import java.util.*;

/**
 * The Polybius Square is essentially identical to the simple substitution cipher,
 * except that each plaintext character is enciphered as 2 ciphertext characters.
 * It can ususally be detected if there are only 5 or 6 different characters in the
 * ciphertext. This algorithm offers very little communication security, and can be
 * easily broken even by hand, especially as the messages become longer (more than
 * several hundred ciphertext characters).
 *
 * @author Piotr 'pitrecki' Nowak
 * @version 0.0.1
 * @see SimpleSubstitutionCipher
 * Created by Pitrecki on 2016-10-30.
 */
public class PolybiusSquareCipher extends ComplexSubstitutionCipher
{
    //Length ====> 25
    private final int KEY_LENGTH = ASCII_TABLE.length - 1;

    private String cipherKey;

    public PolybiusSquareCipher() {
        super();
        keyGenerator();
        squareGenerator(getCipherKey());
    }

    public PolybiusSquareCipher(String key) throws InvalidKeyException {
        super();
        if (!(key.length() == KEY_LENGTH))
            throw new InvalidKeyException("Invalid cipherKey length: " + key.length() + " expected length: 25");
        else if (!isUnigue(key))
            throw new InvalidKeyException("Invalid cipherKey length, expected length: 25");
        else
            this.cipherKey = key.toUpperCase();
        squareGenerator(getCipherKey());
    }

    public String getCipherKey() {
        return cipherKey;
    }


    private void squareGenerator(String key) {
        Character[][] cryptSqaure = new Character[5][5];
        int index = 0;

        for (int i = 0; i < cryptSqaure.length; i++) {
            for (int j = 0; j < cryptSqaure[i].length; j++) {
                cryptSqaure[i][j] = key.charAt(index++);
            }
        }

        setCryptMatrix(cryptSqaure);

    }

    /**
     * Generate unique key
     * List should  prevent from duplicated values
     */
    private void keyGenerator() {
        Set<Character> chKeySet = new LinkedHashSet<>();
        do {
            char letter = ASCII_TABLE[new Random().nextInt(26)];
            if (letter != 'J')
                chKeySet.add(letter);
        } while (chKeySet.size() != KEY_LENGTH);

        this.cipherKey = chKeySet.toString().replaceAll("[\\[\\], ]", "");
    }

    /**
     * This method is responosbile for check is typed key by user is unique
     * @param key input key by user
     * @return true if key length is same, Set colection
     */
    private boolean isUnigue(String key) {
        Set<Character> characterSet = new HashSet<>();
        for (char letter : key.toCharArray())
            characterSet.add(letter);

        return key.length() == characterSet.size();
    }

    @Override
{'fraction_non_alphanumeric': 0.10137569603668523, 'fraction_numerical': 0.008843760235833607, 'mean_word_length': 2.6789156626506023, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2893682', 'n_tokens_mistral': 1751, 'n_tokens_neox': 1641, 'n_words': 515}