Как правильно кодировать и декодировать строку в Base64? - PullRequest
0 голосов
/ 08 марта 2019

Я хочу закодировать строку в Base64 для последующего декодирования. Я кодирую это следующим образом:

public static String encryptString(String string) {     
    byte[] bytesEncoded = Base64.getEncoder().encode(string.getBytes());
    return (new String(bytesEncoded));
}

Затем закодированная строка сохраняется на диске с использованием UTF-8. После перезапуска приложения закодированная строка считывается с диска, и я пытаюсь декодировать строку, используя это:

public static String decryptString(String string) {
    byte[] valueDecoded = Base64.getDecoder().decode(string);
    return (new String(valueDecoded));
}

Что-то не так, потому что это дает мне исключение:

java.lang.IllegalArgumentException: Illegal base64 character d
at java.base/java.util.Base64$Decoder.decode0(Base64.java:743)
at java.base/java.util.Base64$Decoder.decode(Base64.java:535)
at java.base/java.util.Base64$Decoder.decode(Base64.java:558)

Это TRACE шаг за шагом

1º я кодирую это: {"configuration":{"shop":{"name":"","addressLine1":"","addressLine2":"","postalCode":"","city":"","country":"","phoneNumber":""}},"jointBets":[],"groups":[{"name":"Test","members":[]}]}

в это: eyJjb25maWd1cmF0aW9uIjp7InNob3AiOnsibmFtZSI6IiIsImFkZHJlc3NMaW5lMSI6IiIsImFkZHJlc3NMaW5lMiI6IiIsInBvc3RhbENvZGUiOiIiLCJjaXR5IjoiIiwiY291bnRyeSI6IiIsInBob25lTnVtYmVyIjoiIn19LCJqb2ludEJldHMiOltdLCJncm91cHMiOlt7Im5hbWUiOiJUZXN0IiwibWVtYmVycyI6W119XX0=

2º я храню его на диске в utf8

3º я получаю его с диска, и вот эта строка:

eyJjb25maWd1cmF0aW9uIjp7InNob3AiOnsibmFtZSI6IiIsImFkZHJlc3NMaW5lMSI6IiIsImFkZHJlc3NMaW5lMiI6IiIsInBvc3RhbENvZGUiOiIiLCJjaXR5IjoiIiwiY291bnRyeSI6IiIsInBob25lTnVtYmVyIjoiIn19LCJqb2ludEJldHMiOltdLCJncm91cHMiOlt7Im5hbWUiOiJUZXN0IiwibWVtYmVycyI6W119XX0=

4º Я декодирую его и получаю исключение.

Ответы [ 3 ]

0 голосов
/ 08 марта 2019

Затем закодированная строка сохраняется на диске с использованием UTF-8. После перезапуская приложение, закодированная строка считывается с диска и Я пытаюсь декодировать строку, используя это:

Кажется, это точка отказа. Скорее всего, ваша проблема зависит от OS / JDK. Кажется, следующий код мне подходит (Win 7, последняя версия JDK 1.8):

public static void main(String[] args) throws IOException {
    String source = "{\"configuration\":{\"shop\":{\"name\":\"España\",\"addressLine1\":\"\",\"addressLine2\":\"\"," +
                "\"postalCode\":\"\",\"city\":\"\",\"country\":\"\",\"phoneNumber\":\"\"}},\"jointBets\":[]," +
                "\"groups\":[{\"name\":\"Test\",\"members\":[]}]}";

    // Encode string
    String encoded = encryptString(source);

    System.out.println("Base64 encoded: " + encoded);

    // Temp Dir
    String tempDir = System.getProperty("java.io.tmpdir");

    // Write to File
    try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempDir + "data.txt"))) {
        writer.write(encoded);
    }

    // Read from File
    Path path = Paths.get(tempDir + "data.txt");

    Stream<String> lines = Files.lines(path);
    String dataFromFile = lines.collect(Collectors.joining("\n"));
    lines.close();

    // Compare content
    assert encoded.equals(dataFromFile);

    // Decode string
    String decoded = decryptString(dataFromFile);
    System.out.println("Base64 decoded: " + decoded);
}

public static String encryptString(String string) {
    byte[] bytesEncoded = Base64.getEncoder().encode(string.getBytes(StandardCharsets.UTF_8));
    return new String(bytesEncoded);
}

public static String decryptString(String string) {
    byte[] valueDecoded = Base64.getDecoder().decode(string);
    return new String(valueDecoded);
}

Base64 в кодировке: eyJjb25maWd1cmF0aW9uIjp7InNob3AiOnsibmFtZSI6IkVzcGHDsWEiLCJhZGRyZXNzTGluZTEiOiIiLCJhZGRyZXNzTGluZTIiOiIiLCJwb3N0YWxDb2RlIjoiIiwiY2l0eSI6IiIsImNvdW50cnkiOiIiLCJwaG9uZU51bWJlciI6IiJ9fSwiam9pbnRCZXRzIjpbXSwiZ3JvdXBzIjpbeyJuYW1lIjoiVGVzdCIsIm1lbWJlcnMiOltdfV19

Base64 расшифровано: { "Конфигурация": { "магазин": { "имя": "España", "addressLine1": "", "addressLine2": "", "PostalCode": "", "город": "", "страна" : "", "PHONENUMBER": ""}}, "jointBets": [], "группы": [{ "имя": "Тест", "члены": []}]}

0 голосов
/ 19 июня 2019

Старая утилита Base64 добавляет перевод строки через каждые 76 символов в Java8.Результат выглядит так:

/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a
HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy
MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIA
AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3
ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm
...

Кажется, что это поведение изменилось в какой-то версии.По крайней мере, в Java11 декодер больше не принимает переносы строк.Чтобы избежать проблемы, вы можете изменить свой метод

public static String decryptString(String string) {
    byte[] valueDecoded = Base64.getDecoder().decode(string.replace("\n","").replace("\r","");
    return new String(valueDecoded);
}
0 голосов
/ 08 марта 2019

Я предполагаю, что вы не указываете кодировку.Попробуйте выполнить приведенное ниже, возможно, с и без кодировки, указанной для конструктора String, для проверки.

   @Test
    public void base64Test() throws Exception{
        String string = "ABCDF";

        byte[] bytesEncoded = Base64.getEncoder().encode(string.getBytes());
        String encodedStr = (new String(bytesEncoded,Charset.forName("ISO-8859-1")));
        System.out.println(encodedStr);

        byte[] valueDecoded = Base64.getDecoder().decode(encodedStr);
        String decodedStr = (new String(valueDecoded,Charset.forName("ISO-8859-1")));
        System.out.println(decodedStr);
    }
...