mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-08-02 06:03:41 +08:00
Format code with prettier (#3375)
This commit is contained in:
@ -4,21 +4,22 @@ import java.util.BitSet;
|
||||
|
||||
// https://en.wikipedia.org/wiki/A5/1
|
||||
public class A5Cipher {
|
||||
|
||||
private final A5KeyStreamGenerator keyStreamGenerator;
|
||||
private static final int KEY_STREAM_LENGTH = 228; // 28.5 bytes so we need to pad bytes or something
|
||||
|
||||
public A5Cipher( BitSet sessionKey, BitSet frameCounter ) {
|
||||
public A5Cipher(BitSet sessionKey, BitSet frameCounter) {
|
||||
keyStreamGenerator = new A5KeyStreamGenerator();
|
||||
keyStreamGenerator.initialize( sessionKey, frameCounter );
|
||||
keyStreamGenerator.initialize(sessionKey, frameCounter);
|
||||
}
|
||||
|
||||
public BitSet encrypt( BitSet plainTextBits ) {
|
||||
public BitSet encrypt(BitSet plainTextBits) {
|
||||
// create a copy
|
||||
var result = new BitSet( KEY_STREAM_LENGTH );
|
||||
result.xor( plainTextBits );
|
||||
var result = new BitSet(KEY_STREAM_LENGTH);
|
||||
result.xor(plainTextBits);
|
||||
|
||||
var key = keyStreamGenerator.getNextKeyStream();
|
||||
result.xor( key );
|
||||
result.xor(key);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -26,5 +27,4 @@ public class A5Cipher {
|
||||
public void resetCounter() {
|
||||
keyStreamGenerator.reInitialize();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import java.util.BitSet;
|
||||
|
||||
// TODO: raise exceptions for improper use
|
||||
public class A5KeyStreamGenerator extends CompositeLFSR {
|
||||
|
||||
private BitSet initialFrameCounter;
|
||||
private BitSet frameCounter;
|
||||
private BitSet sessionKey;
|
||||
@ -11,32 +12,35 @@ public class A5KeyStreamGenerator extends CompositeLFSR {
|
||||
private static final int KEY_STREAM_LENGTH = 228; // 28.5 bytes so we need to pad bytes or something
|
||||
|
||||
@Override
|
||||
public void initialize( BitSet sessionKey, BitSet frameCounter ) {
|
||||
public void initialize(BitSet sessionKey, BitSet frameCounter) {
|
||||
this.sessionKey = sessionKey;
|
||||
this.frameCounter = (BitSet) frameCounter.clone();
|
||||
this.initialFrameCounter = (BitSet) frameCounter.clone();
|
||||
registers.clear();
|
||||
LFSR lfsr1 = new LFSR( 19, 8, new int[]{ 13, 16, 17, 18 } );
|
||||
LFSR lfsr2 = new LFSR( 22, 10, new int[]{ 20, 21 } );
|
||||
LFSR lfsr3 = new LFSR( 23, 10, new int[]{ 7, 20, 21, 22 } );
|
||||
registers.add( lfsr1 );
|
||||
registers.add( lfsr2 );
|
||||
registers.add( lfsr3 );
|
||||
registers.forEach( lfsr -> lfsr.initialize( sessionKey, frameCounter ) );
|
||||
LFSR lfsr1 = new LFSR(19, 8, new int[] { 13, 16, 17, 18 });
|
||||
LFSR lfsr2 = new LFSR(22, 10, new int[] { 20, 21 });
|
||||
LFSR lfsr3 = new LFSR(23, 10, new int[] { 7, 20, 21, 22 });
|
||||
registers.add(lfsr1);
|
||||
registers.add(lfsr2);
|
||||
registers.add(lfsr3);
|
||||
registers.forEach(lfsr -> lfsr.initialize(sessionKey, frameCounter));
|
||||
}
|
||||
|
||||
public void reInitialize() {
|
||||
this.initialize( sessionKey, initialFrameCounter );
|
||||
this.initialize(sessionKey, initialFrameCounter);
|
||||
}
|
||||
|
||||
public BitSet getNextKeyStream() {
|
||||
for ( int cycle = 1; cycle <= INITIAL_CLOCKING_CYCLES; ++cycle )
|
||||
this.clock();
|
||||
for (
|
||||
int cycle = 1;
|
||||
cycle <= INITIAL_CLOCKING_CYCLES;
|
||||
++cycle
|
||||
) this.clock();
|
||||
|
||||
BitSet result = new BitSet( KEY_STREAM_LENGTH );
|
||||
for ( int cycle = 1; cycle <= KEY_STREAM_LENGTH; ++cycle ) {
|
||||
BitSet result = new BitSet(KEY_STREAM_LENGTH);
|
||||
for (int cycle = 1; cycle <= KEY_STREAM_LENGTH; ++cycle) {
|
||||
boolean outputBit = this.clock();
|
||||
result.set( cycle - 1, outputBit );
|
||||
result.set(cycle - 1, outputBit);
|
||||
}
|
||||
|
||||
reInitializeRegisters();
|
||||
@ -45,10 +49,10 @@ public class A5KeyStreamGenerator extends CompositeLFSR {
|
||||
|
||||
private void reInitializeRegisters() {
|
||||
incrementFrameCounter();
|
||||
registers.forEach( lfsr -> lfsr.initialize( sessionKey, frameCounter ) );
|
||||
registers.forEach(lfsr -> lfsr.initialize(sessionKey, frameCounter));
|
||||
}
|
||||
|
||||
private void incrementFrameCounter() {
|
||||
Utils.increment( frameCounter, FRAME_COUNTER_LENGTH );
|
||||
Utils.increment(frameCounter, FRAME_COUNTER_LENGTH);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public abstract class CompositeLFSR implements BaseLFSR {
|
||||
|
||||
protected final List<LFSR> registers = new ArrayList<>();
|
||||
|
||||
/**
|
||||
@ -16,20 +17,24 @@ public abstract class CompositeLFSR implements BaseLFSR {
|
||||
public boolean clock() {
|
||||
boolean majorityBit = getMajorityBit();
|
||||
boolean result = false;
|
||||
for ( var register : registers ) {
|
||||
for (var register : registers) {
|
||||
result ^= register.getLastBit();
|
||||
if ( register.getClockBit() == majorityBit )
|
||||
register.clock();
|
||||
if (register.getClockBit() == majorityBit) register.clock();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean getMajorityBit() {
|
||||
Map<Boolean, Integer> bitCount = new TreeMap<>();
|
||||
bitCount.put( false, 0 );
|
||||
bitCount.put( true, 0 );
|
||||
bitCount.put(false, 0);
|
||||
bitCount.put(true, 0);
|
||||
|
||||
registers.forEach( lfsr -> bitCount.put( lfsr.getClockBit(), bitCount.get( lfsr.getClockBit() ) + 1 ) );
|
||||
return bitCount.get( false ) <= bitCount.get( true );
|
||||
registers.forEach(lfsr ->
|
||||
bitCount.put(
|
||||
lfsr.getClockBit(),
|
||||
bitCount.get(lfsr.getClockBit()) + 1
|
||||
)
|
||||
);
|
||||
return bitCount.get(false) <= bitCount.get(true);
|
||||
}
|
||||
}
|
||||
|
@ -3,71 +3,72 @@ package com.thealgorithms.ciphers.a5;
|
||||
import java.util.BitSet;
|
||||
|
||||
public class LFSR implements BaseLFSR {
|
||||
|
||||
private final BitSet register;
|
||||
private final int length;
|
||||
private final int clockBitIndex;
|
||||
private final int[] tappingBitsIndices;
|
||||
|
||||
public LFSR( int length, int clockBitIndex, int[] tappingBitsIndices ) {
|
||||
public LFSR(int length, int clockBitIndex, int[] tappingBitsIndices) {
|
||||
this.length = length;
|
||||
this.clockBitIndex = clockBitIndex;
|
||||
this.tappingBitsIndices = tappingBitsIndices;
|
||||
register = new BitSet( length );
|
||||
register = new BitSet(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize( BitSet sessionKey, BitSet frameCounter ) {
|
||||
public void initialize(BitSet sessionKey, BitSet frameCounter) {
|
||||
register.clear();
|
||||
clock( sessionKey, SESSION_KEY_LENGTH );
|
||||
clock( frameCounter, FRAME_COUNTER_LENGTH );
|
||||
clock(sessionKey, SESSION_KEY_LENGTH);
|
||||
clock(frameCounter, FRAME_COUNTER_LENGTH);
|
||||
}
|
||||
|
||||
private void clock( BitSet key, int keyLength ) {
|
||||
private void clock(BitSet key, int keyLength) {
|
||||
// We start from reverse because LFSR 0 index is the left most bit
|
||||
// while key 0 index is right most bit, so we reverse it
|
||||
for ( int i = keyLength - 1; i >= 0; --i ) {
|
||||
var newBit = key.get( i ) ^ xorTappingBits();
|
||||
pushBit( newBit );
|
||||
for (int i = keyLength - 1; i >= 0; --i) {
|
||||
var newBit = key.get(i) ^ xorTappingBits();
|
||||
pushBit(newBit);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clock() {
|
||||
return pushBit( xorTappingBits() );
|
||||
return pushBit(xorTappingBits());
|
||||
}
|
||||
|
||||
public boolean getClockBit() {
|
||||
return register.get( clockBitIndex );
|
||||
return register.get(clockBitIndex);
|
||||
}
|
||||
|
||||
public boolean get( int bitIndex ) {
|
||||
return register.get( bitIndex );
|
||||
public boolean get(int bitIndex) {
|
||||
return register.get(bitIndex);
|
||||
}
|
||||
|
||||
public boolean getLastBit() {
|
||||
return register.get( length - 1 );
|
||||
return register.get(length - 1);
|
||||
}
|
||||
|
||||
private boolean xorTappingBits() {
|
||||
boolean result = false;
|
||||
for ( int i : tappingBitsIndices ) {
|
||||
result ^= register.get( i );
|
||||
for (int i : tappingBitsIndices) {
|
||||
result ^= register.get(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean pushBit( boolean bit ) {
|
||||
private boolean pushBit(boolean bit) {
|
||||
boolean discardedBit = rightShift();
|
||||
register.set( 0, bit );
|
||||
register.set(0, bit);
|
||||
return discardedBit;
|
||||
}
|
||||
|
||||
private boolean rightShift() {
|
||||
boolean discardedBit = get( length - 1 );
|
||||
for ( int i = length - 1; i > 0; --i ) {
|
||||
register.set( i, get( i - 1 ) );
|
||||
boolean discardedBit = get(length - 1);
|
||||
for (int i = length - 1; i > 0; --i) {
|
||||
register.set(i, get(i - 1));
|
||||
}
|
||||
register.set( 0, false );
|
||||
register.set(0, false);
|
||||
return discardedBit;
|
||||
}
|
||||
|
||||
|
@ -7,15 +7,16 @@ package com.thealgorithms.ciphers.a5;
|
||||
import java.util.BitSet;
|
||||
|
||||
public class Utils {
|
||||
public static boolean increment( BitSet bits, int size ) {
|
||||
|
||||
public static boolean increment(BitSet bits, int size) {
|
||||
int i = size - 1;
|
||||
while ( i >= 0 && bits.get( i ) ) {
|
||||
bits.set( i--, false );/*from w w w . j a v a 2s .c o m*/
|
||||
while (i >= 0 && bits.get(i)) {
|
||||
bits.set(i--, false);/*from w w w . j a v a 2s .c o m*/
|
||||
}
|
||||
if ( i < 0 ) {
|
||||
if (i < 0) {
|
||||
return false;
|
||||
}
|
||||
bits.set( i, true );
|
||||
bits.set(i, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user