Nanyou Cryptography Experiment 1 – Java

The code is relatively bad, and there are some strange bugs, just for reference

package src;


import lombok. AllArgsConstructor;
import lombok.Data;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Abstraction of geared machines
 *
 * @author zhou
 * @date 2023/2/28
 */
@Data
@AllArgsConstructor
public class Gear {
    private LinkedHashMap<Character,Integer> forwardCharacterMap;
    private LinkedHashMap<Integer,Character> backwardCharacterMap;
    private LinkedHashMap<Integer,Integer> forwardBindMap;
    private LinkedHashMap<Integer,Integer> backwardBindMap;
    private HashMap<Character,Integer> count;
    int pushCountFast;
    int pushCountMid;


    public Gear(){

        this.forwardCharacterMap = new LinkedHashMap<>();
        this.forwardBindMap = new LinkedHashMap<>();
        this.backwardBindMap = new LinkedHashMap<>();
        this.backwardCharacterMap = new LinkedHashMap<>();
        this.count = new HashMap<>();

        forwardCharacterMap.put('A',24);
        forwardCharacterMap. put('B',25);
        forwardCharacterMap. put('C',26);
        forwardCharacterMap. put('D',1);
        forwardCharacterMap. put('E',2);
        forwardCharacterMap. put('F',3);
        forwardCharacterMap.put('G',4);
        forwardCharacterMap.put('H',5);
        forwardCharacterMap. put('I',6);
        forwardCharacterMap. put('J',7);
        forwardCharacterMap.put('K',8);
        forwardCharacterMap.put('L',9);
        forwardCharacterMap.put('M',10);
        forwardCharacterMap. put('N',11);
        forwardCharacterMap. put('O',12);
        forwardCharacterMap.put('P',13);
        forwardCharacterMap.put('Q',14);
        forwardCharacterMap. put('R',15);
        forwardCharacterMap.put('S',16);
        forwardCharacterMap. put('T',17);
        forwardCharacterMap.put('U',18);
        forwardCharacterMap.put('V',19);
        forwardCharacterMap. put('W',20);
        forwardCharacterMap. put('X',21);
        forwardCharacterMap.put('Y',22);
        forwardCharacterMap.put('Z',23);

        forwardBindMap.put(21,26);
        forwardBindMap.put(3,1);
        forwardBindMap.put(15,2);
        forwardBindMap. put(1,3);
        forwardBindMap.put(19,4);
        forwardBindMap.put(10,5);
        forwardBindMap.put(14,6);
        forwardBindMap.put(26,7);
        forwardBindMap.put(20,8);
        forwardBindMap.put(8,9);
        forwardBindMap.put(16,10);
        forwardBindMap.put(7,11);
        forwardBindMap.put(22,12);
        forwardBindMap.put(4,13);
        forwardBindMap.put(11,14);
        forwardBindMap.put(5,15);
        forwardBindMap.put(17,16);
        forwardBindMap.put(9,17);
        forwardBindMap.put(12,18);
        forwardBindMap.put(23,19);
        forwardBindMap.put(18,20);
        forwardBindMap.put(2,21);
        forwardBindMap.put(25,22);
        forwardBindMap. put(6,23);
        forwardBindMap.put(24,24);
        forwardBindMap.put(13,25);

        backwardBindMap.put(20,1);
        backwardBindMap. put(1,2);
        backwardBindMap. put(6,3);
        backwardBindMap. put(4,4);
        backwardBindMap.put(15,5);
        backwardBindMap. put(3,6);
        backwardBindMap. put(14,7);
        backwardBindMap.put(12,8);
        backwardBindMap.put(23,9);
        backwardBindMap. put(5,10);
        backwardBindMap.put(16,11);
        backwardBindMap. put(2,12);
        backwardBindMap.put(22,13);
        backwardBindMap.put(19,14);
        backwardBindMap.put(11,15);
        backwardBindMap.put(18,16);
        backwardBindMap.put(25,17);
        backwardBindMap.put(24,18);
        backwardBindMap.put(13,19);
        backwardBindMap. put(7,20);
        backwardBindMap.put(10,21);
        backwardBindMap.put(8,22);
        backwardBindMap.put(21,23);
        backwardBindMap.put(9,24);
        backwardBindMap.put(26,25);
        backwardBindMap. put(17,26);
        
        backwardCharacterMap.put(8,'A');
        backwardCharacterMap. put(18,'B');
        backwardCharacterMap. put(26,'C');
        backwardCharacterMap. put(17,'D');
        backwardCharacterMap. put(20,'E');
        backwardCharacterMap. put(22,'F');
        backwardCharacterMap.put(10,'G');
        backwardCharacterMap.put(3,'H');
        backwardCharacterMap. put(13,'I');
        backwardCharacterMap.put(11,'G');
        backwardCharacterMap.put(4,'K');
        backwardCharacterMap. put(23,'L');
        backwardCharacterMap. put(5,'M');
        backwardCharacterMap.put(24,'N');
        backwardCharacterMap. put(9,'O');
        backwardCharacterMap.put(12,'P');
        backwardCharacterMap.put(25,'Q');
        backwardCharacterMap.put(16,'R');
        backwardCharacterMap.put(19,'S');
        backwardCharacterMap.put(6,'T');
        backwardCharacterMap.put(15,'U');
        backwardCharacterMap.put(21,'V');
        backwardCharacterMap. put(2,'W');
        backwardCharacterMap.put(7,'X');
        backwardCharacterMap. put(1,'Y');
        backwardCharacterMap. put(14,'Z');

        count. put('A',0);
        count. put('B',0);
        count. put('Q',0);
        count. put('W',0);
        count. put('E',0);
        count. put('R',0);
        count. put('T',0);
        count. put('Y',0);
        count. put('U',0);
        count. put('I',0);
        count. put('O',0);
        count. put('P',0);
        count. put('D',0);
        count. put('S',0);
        count. put('F',0);
        count. put('G',0);
        count. put('H',0);
        count. put('J',0);
        count. put('K',0);
        count. put('L',0);
        count. put('Z',0);
        count. put('X',0);
        count. put('C',0);
        count. put('V',0);
        count. put('N',0);
        count. put('M',0);


    }

    private <K,V>void upLeft(Map<K,V> map){
        Iterator<K> it = map.keySet().iterator();
        K now = it. next();
        K next = it. next();
        V cache = map. get(now);
        while (it. hasNext()) {
            map. replace(now, map. get(next));
            now = next;
            next = it. next();
        }
        map.replace(next,cache);
    }

    private <K,V>void lowRight(Map<K,V> map){
        Iterator<K> it = map.keySet().iterator();
        K head = it. next();
        K front = head;
        K now = it. next();
        while (it. hasNext()) {
            map. replace(now, map. get(front));
            front = now;
            now = it. next();
        }
        map.replace(head, map.get(now));
    }

    public Boolean push(){
        pushCountFast++;
        if(pushCountFast==27){
            pushCountFast=0;
            pushCountMid++;
            if(pushCountMid==27){
                pushCountMid=0;
                upLeft(forwardCharacterMap);
                lowRight(forwardBindMap);
            }
            upLeft(forwardBindMap);
            lowRight(backwardBindMap);
        }
        upLeft(backwardBindMap);
        lowRight(backwardCharacterMap);
        return true;
    }

    public List<Character> getEncCode(List<Character> originCode){
        AtomicInteger countAll = new AtomicInteger();
        List<Character> encCode = new ArrayList<>();
        originCode.forEach(b->{
            if(Character. isAlphabetic(b)){
                encCode.add(
                        backwardCharacterMap. get(
                                backwardBindMap.get(
                                        forwardBindMap.get(
                                                forwardCharacterMap. get(b)
                                        )
                                )
                        )
                );
                if(count. containsKey(Character. toUpperCase(b))){
                    count.replace(
                            Character.toUpperCase(b),
                            count.get(Character.toUpperCase(b)) + 1
                    );
                    countAll. getAndIncrement();
                }
            } else{
                encCode. add(b);
            }
        });
        double all = countAll. get();
        count.forEach((k,v)->{
            System.out.println(k + ":" + v/all);
            count.replace(k,0);
        });
        return encCode;
    }

    public List<Character> getDecCode(List<Character> encCode){
        List<Character> decCode = new ArrayList<>();
        encCode.forEach(b->{
            if(Character. isAlphabetic(b)){
                backwardCharacterMap. entrySet()
                        .stream()
                        .filter(kvEntry -> Objects.equals(kvEntry.getValue(), b))
                        .map(Map.Entry::getKey)
                        .forEach(o->backwardBindMap.entrySet()
                                .stream()
                                .filter(kvEntry -> Objects.equals(kvEntry.getValue(), o))
                                .map(Map.Entry::getKey)
                                .forEach(a->forwardBindMap.entrySet()
                                        .stream()
                                        .filter(kvEntry -> Objects.equals(kvEntry.getValue(), a))
                                        .map(Map.Entry::getKey)
                                        .forEach(c->forwardCharacterMap.entrySet()
                                                .stream()
                                                .filter(kvEntry -> Objects.equals(kvEntry.getValue(), c))
                                                .map(Map.Entry::getKey)
                                                .forEach(decCode::add)
                                        )
                                )
                        );
            } else
                decCode. add(b);
        });
        return decCode;
    }
}
package src;

import java.util.*;

/**
 *The main program to run·
 *
 *@author zhou
 *@date 2023/2/28
 */
public class Enigma {
    public static void main(String[] args) {
        Gear gear = new Gear();
        while(true){
            System.out.println("select mode");
            System.out.println("encryption mode-1");
            System.out.println("Decryption mode-2");
            System.out.println("Push the wheel-3");
            Scanner scanner = new Scanner(System.in);
            switch(scanner. nextInt()){
                case 1->{
                    List<Character> cs = new ArrayList<>();
                    char[] ca = scanner.next().toCharArray();
                    for(char c:ca){
                        cs.add(Character.toUpperCase(c));
                    }
                    gear.getEncCode(cs).forEach(System.out::print);
                    System.out.println();
                }
                case 2->{
                    List<Character> cs = new ArrayList<>();
                    char[] ca = scanner.next().toCharArray();
                    for(char c:ca){
                        cs.add(Character.toUpperCase(c));
                    }
                    gear.getDecCode(cs).forEach(System.out::print);
                    System.out.println();
                }
                case 3->{
                    gear. push();
                }
                default -> {
                    return;
                }
            }
        }
    }
}