Cifrado y descifrado Winnowing en Java

Esto es una especie de cifrado Winnowing, al cual le pasas el mensaje y una clave numérica.
El mensaje cifrado que devuelve se calcula de la siguiente manera:
-Coge el mensaje. Entre una letra y otra, mete dos letras inútiles de forma aleatoria.
-Cada letra del mensaje se calcula desplazando la letra tantas posiciones como nos dicte la clave numérica.
Para descifrar el mensaje:
-Coge el mensaje, le quita las letras sobrantes y resta a cada letra tantas posiciones como dicte la clave numérica.



public class Winnowing {

private static String alfabeto = "abcdefghijklmnñopqrstuvwxyzABCDEFGHIJKLMNÑOPQ-RSTUVWXYZáéíóúÁÉÍÓÚ0123456789 _,.;:?!";

public static void main(String[] args) {
// TODO Auto-generated method stub
String a = cifrar("Hola esto es un mensaje de prueba", 3);
String b = descifrar(a, 3);
}

public static String cifrar(String texto, int clave){
int[] msg = pasarTextoNumero(texto);

int[] msgConBasura = new int[msg.length*3];

int contador = 0;
for (int i = 0; i < msg.length; i++) {
int numeroLetra = (msg[i]+clave)%alfabeto.length();
msgConBasura[contador]=numeroLetra;
contador++;
msgConBasura[contador]=getRandomArbitrary(0,alfabeto.length()-1);
contador++;
msgConBasura[contador]=getRandomArbitrary(0,alfabeto.length()-1);
contador++;
}

String sol = "";
for (int i = 0; i < msgConBasura.length; i++) {
int posLetra = msgConBasura[i]-1;
if(posLetra<0){
posLetra=posLetra+alfabeto.length();
}
sol+=alfabeto.charAt(posLetra);
}

System.out.println(sol+" "+msg.length+" "+msgConBasura.length);
return sol;
}

public static String descifrar(String texto, int clave){
int[] msg = pasarTextoNumero(texto);

int[] msgSinBasura = new int[msg.length/3];

for (int i = 0; i < msg.length; i+=3) {
int numeroLetra = msg[i]-clave;
if(numeroLetra<0){
numeroLetra=alfabeto.length()+numeroLetra;
}
msgSinBasura[i/3]=numeroLetra;

}

String sol = "";
for (int i = 0; i < msgSinBasura.length; i++) {
int posLetra = msgSinBasura[i]-1;
if(posLetra<0){
posLetra=posLetra+alfabeto.length();
}
sol+=alfabeto.charAt(posLetra);
}

System.out.println(sol+" "+msg.length+" "+msgSinBasura.length);
return sol;
}

// Retorna un número aleatorio entre min (incluido) y max (excluido)
private static int getRandomArbitrary(int min, int max) {
 return (int) (Math.random() * (max - min) + min);
}

//pasa un String a un int[] con el valor de cada letra en el alfabeto
private static int[] pasarTextoNumero(String mensaje){
int[] secuencia = new int[mensaje.length()];//array con la longitud del mensaje
for (int i = 0; i < secuencia.length; i++) {
char letra = mensaje.charAt(i);
int valor = valorLetra(letra);
secuencia[i]=(valor+1)%alfabeto.length();
}
return secuencia;
}

//devuelve la posicion de la letra en el alfabeto
private static int valorLetra(char letra){
for (int j = 0; j < alfabeto.length(); j++) {
if(letra==alfabeto.charAt(j)){
return j;
}
}
return -1;
}

}