- ВКонтакте
- РћРТвЂВВВВВВВВнокласснРСвЂВВВВВВВВРєРСвЂВВВВВВВВ
- РњРѕР№ Р В Р’В Р РЋРЎв„ўР В Р’В Р РЋРІР‚ВВВВВВВВРЎР‚
- Viber
- Skype
- Telegram
Почему не шифруются русские символы?
Почему данный код шифрует все символы, кроме русских?
Здесь я ищу и заменяю символ в алфавите:
private void encrypting(Path sourcePath, Path resultPath, List<Character> alphabet, int key) {
try (FileChannel source = FileChannel.open(sourcePath, StandardOpenOption.READ);
FileChannel result = FileChannel.open(resultPath, StandardOpenOption.WRITE)) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (source.read(buffer) != -1) {
buffer.flip();
while (buffer.hasRemaining()) {
byte b = buffer.get();
char c = (char) b;
int index = alphabet.indexOf(c);
if (index != -1) {
int newIndex = Math.floorMod(index + key, alphabet.size());
char encrypted = alphabet.get(newIndex);
result.write(ByteBuffer.wrap(new byte[]{(byte) encrypted}));
} else {
result.write(ByteBuffer.wrap(new byte[]{(byte) c}));
}
}
buffer.clear();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Здесь русские буквы добавляются в алфавит:
for (char i = 'А'; i <= 'Я'; i++) {
alphabet.add(i);
}
for (char i = 'а'; i <= 'я'; i++) {
alphabet.add(i);
}
Исходная строка, которую надо было зашифровать:
Бородино Borodino 1234567890(),?>
И результат шифрования:
Бородино%Gtwtinst%6789:;<=>5-.1ED
Почему данный код шифрует все символы, кроме русского алфавита?
Ответы (1 шт):
В большинстве случаев буковки русского алфавита хранятся в файлах не в одном байте, а в нескольких. Правило представления буковов последовательностью байтов, называется кодировкой. В современном мире наиболее распространённой кодировкой является UTF-8.
Но к вашему и нашему счастию разработчики JRE уже позаботились о том, чтобы перекодировать из байтов в буквы и обратно. Этим занимаются классы, реализующие абстрактные классы java.io.Reader
и java.io.Writer
.
Поэтому вам стоит в вашем шифровальщике работать не файловыми каналами и самостоятельно реализовывать декодирование байты-символы, а воспользоваться стандартной библиотекой:
public void encrypt(Reader in, Writer out, int key) throws IOException {
for (int i = in.read(); i >= 0; i = in.read()) {
char ch = (char) i;
int index = alphabet.indexOf(ch);
if (index != -1) {
int newIndex = (index + key) % alphabet.size();
char encrypted = alphabet.get(newIndex);
out.write(encrypted);
} else {
out.write(ch);
}
}
}
Теперь как Path
в превратить в читателя-писателя:
public void encrypt(Path sourcePath, Path resultPath, int key) throws IOException {
var in = Files.newBufferedReader(sourcePath); // UTF-8 by default
try {
var out = Files.newBufferedWriter(resultPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE); // UTF-8
// by
// default
try {
encrypt(in, out, key);
} finally {
out.close();
}
} finally {
in.close();
}
}
Как шифровать:
public static void main(String[] argv) throws Exception {
System.out.println("Hello, world!");
var enc = new Encrypt();
enc.encrypt(Paths.get("in.txt"), Paths.get("out.txt"), 2);
}
Исходный файл Бородино Borodino 1234567890
Результат: Гртржкпр Dqtqfkpq 3456789АБ2
Класс Encrypt
целиком
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.LinkedList;
import java.util.List;
public class Encrypt {
public static List<Character> initAlphabet() {
var alphabet = new LinkedList<Character>();
for (char i = 'A'; i <= 'Z'; i++) {
alphabet.add(i);
}
for (char i = 'a'; i <= 'z'; i++) {
alphabet.add(i);
}
for (char i = '0'; i <= '9'; i++) {
alphabet.add(i);
}
for (char i = 'А'; i <= 'Я'; i++) {
alphabet.add(i);
}
for (char i = 'а'; i <= 'я'; i++) {
alphabet.add(i);
}
return alphabet;
}
public final List<Character> alphabet = initAlphabet();
public void encrypt(Reader in, Writer out, int key) throws IOException {
for (int i = in.read(); i >= 0; i = in.read()) {
char ch = (char) i;
int index = alphabet.indexOf(ch);
if (index != -1) {
int newIndex = (index + key) % alphabet.size();
char encrypted = alphabet.get(newIndex);
out.write(encrypted);
} else {
out.write(ch);
}
}
}
public void encrypt(Path sourcePath, Path resultPath, int key) throws IOException {
var in = Files.newBufferedReader(sourcePath); // UTF-8 by default
try {
var out = Files.newBufferedWriter(resultPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE); // UTF-8
// by
// default
try {
encrypt(in, out, key);
} finally {
out.close();
}
} finally {
in.close();
}
}
}