Подумайте, что вам нужно - просто file.read()
и file.getChannel().size()
, чтобы прочитать по одному символу за раз и получить размер файла
Попробуйте что-то вроде этого:
private static int[] encrypt(FileInputStream file, String key) {
int fileSize = file.getChannel().size();
int[] output = new int[fileSize];
for(int i = 0; i < output.length; i++) {
char char1 = (char) file.read();
int o = (char1 ^ Integer.valueOf(key.charAt(i % (key.length() - 1)))) + '0';
output[i] = o;
}
return output;
}
Придется выполнить некоторую обработку ошибок, потому что file.read () вернет -1, если достигнут конец файла, и, как указано, чтение по одному байту за раз является большим количеством операций ввода-вывода и может снизить производительность. Вы можете хранить данные в буфере и читать их по-другому, например так:
private static int[] encrypt(FileInputStream file, String key) {
int fileSize = file.getChannel().size();
int[] output = new int[fileSize];
int read = 0;
int offset = 0;
byte[] buffer = new byte[1024];
while((read = file.read(buffer)) > 0) {
for(int i = 0; i < read; i++) {
char char1 = (char) buffer[i];
int o = (char1 ^ Integer.valueOf(key.charAt(i % (key.length() - 1)))) + '0';
output[i + offset] = o;
}
offset += read;
}
return output;
}
Это будет считывать из файла 1024 байта за раз и сохранять их в буфере, затем вы можете l oop через буфер, чтобы сделать логи c. Значение смещения должно хранить, где в нашем выводе находится текущее место. Также вам нужно убедиться, что i + offset
не превышает размер вашего массива.
ОБНОВЛЕНИЕ
После работы с ним; Я решил переключиться на Base64 Encoding / Decoding, чтобы удалить непечатаемые символы:
private static String encrypt(InputStream file, String key) throws Exception {
int read = 0;
byte[] buffer = new byte[1024];
try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
while((read = file.read(buffer)) > 0) {
baos.write(buffer, 0, read);
}
return base64Encode(xorWithKey(baos.toByteArray(), key.getBytes()));
}
}
private static String decrypt(String input, String key) {
byte[] decoded = base64Decode(input);
return new String(xorWithKey(decoded, key.getBytes()));
}
private static byte[] xorWithKey(byte[] a, byte[] key) {
byte[] out = new byte[a.length];
for (int i = 0; i < a.length; i++) {
out[i] = (byte) (a[i] ^ key[i%key.length]);
}
return out;
}
private static byte[] base64Decode(String s) {
return Base64.getDecoder().decode(s.trim());
}
private static String base64Encode(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
Этот метод более понятен и не требует знания размера InputStream
или каких-либо преобразований символов. Он читает ваш InputStream
в OutputStream для выполнения кодирования Base64, а также для удаления непечатаемых символов.
Я проверил это, и он работает как для шифрования, так и для дешифрования.
Я получил идея из этого ответа:
операция XOR с двумя строками в java