Как закодировать Карту <Строка, Строка> как строка Base64?

мне нравится кодировать карту Java строк как единственная основа 64 закодированных строки. Закодированная строка будет передаваться к удаленной конечной точке и возможно управляться не хорошим человеком. Таким образом, худшая вещь, которая должна произойти, является недопустимым ключом, кортежами значения, но не должна приносить никакие другие угрозы безопасности в стороне.

Пример:

Map map = ...
String encoded = Base64.encode(map);

// somewhere else
Map map = Base64.decode(encoded);

Да, должен быть Base64. Не как этот или это или любые другие из них. Существует ли существующее легкое решение (Единственный предпочтенный Utils-класс) там? Или я должен создать свое собственное?

Что-нибудь лучше, чем это?

// marshalling
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(map);
oos.close();
String encoded = new String(Base64.encodeBase64(baos.toByteArray()));

// unmarshalling 
byte[] decoded = Base64.decodeBase64(encoded.getBytes());
ByteArrayInputStream bais = new ByteArrayInputStream(decoded);
ObjectInputStream ois = new ObjectInputStream(bais);
map = (Map) ois.readObject();
ois.close();

Спасибо,

7
задан Chris 8 February 2010 в 12:08
поделиться

3 ответа

Мои основные требования: закодированная строка должна быть как можно короче и содержать только латинские символы или символы из алфавита base64 (не мой призыв). других требований нет.

Используйте Google Gson , чтобы преобразовать карту в JSON . Используйте GZIPOutputStream для сжатия строки JSON. Используйте Кодек Apache Commons Base64 или Base64OutputStream для кодирования сжатых байтов в строку Base64.

Начальный пример:

public static void main(String[] args) throws IOException {
    Map<String, String> map = new HashMap<String, String>();
    map.put("key1", "value1");
    map.put("key2", "value2");
    map.put("key3", "value3");

    String serialized = serialize(map);
    Map<String, String> deserialized = deserialize(serialized, new TypeToken<Map<String, String>>() {}.getType());

    System.out.println(deserialized);
}

public static String serialize(Object object) throws IOException {
    ByteArrayOutputStream byteaOut = new ByteArrayOutputStream();
    GZIPOutputStream gzipOut = null;
    try {
        gzipOut = new GZIPOutputStream(new Base64OutputStream(byteaOut));
        gzipOut.write(new Gson().toJson(object).getBytes("UTF-8"));
    } finally {
        if (gzipOut != null) try { gzipOut.close(); } catch (IOException logOrIgnore) {}
    }
    return new String(byteaOut.toByteArray());
}

public static <T> T deserialize(String string, Type type) throws IOException {
    ByteArrayOutputStream byteaOut = new ByteArrayOutputStream();
    GZIPInputStream gzipIn = null;
    try {
        gzipIn = new GZIPInputStream(new Base64InputStream(new ByteArrayInputStream(string.getBytes("UTF-8"))));
        for (int data; (data = gzipIn.read()) > -1;) {
            byteaOut.write(data);
        }
    } finally {
        if (gzipIn != null) try { gzipIn.close(); } catch (IOException logOrIgnore) {}
    }
    return new Gson().fromJson(new String(byteaOut.toByteArray()), type);
}
13
ответ дан 6 December 2019 в 12:50
поделиться

Другой возможный способ - использовать JSON , который является очень облегченной библиотекой. В этом случае кодировка будет выглядеть так:

JSONObject jso = new JSONObject( map );
String encoded = new String(Base64.encodeBase64( jso.toString( 4 ).toByteArray()));
2
ответ дан 6 December 2019 в 12:50
поделиться

Попробуйте {{course.student_set.all.0}} . Механизм шаблонов не допускает произвольного кода, а синтаксис доступа к методу отличается от обычного кода Python. Я рекомендую прочитать этот обзор , чтобы понять, как работают шаблоны

-121--3894363-

По адресу:

  1. Вы назначаете значение указателю q , удалив его из адреса в конкретную память см. Документ по отмене привязки указателя . Однако из-за состояния , при котором устанавливается адрес x , он может указывать на ячейку произвольного запоминающего устройства (не инициализирована), если x < = 0 .
  2. В строке выше задается q для указания на тот же адрес памяти, что и p . Затем для p выделяется новая память. Затем выделяется новая память, к которой точки p .
  3. Строка над вами удалила выделение памяти, указанное q . Теперь этот адрес памяти доступен для использования системой. И после этого вы присваиваете памяти значение, которое не «принадлежит» вам.
  4. Если x = 0 , то возвращается к системной памяти, на которую указывают q и p . И снова попытка использовать память, которая не «принадлежит» вам. Также отсутствует delete p , если x! = 0 - таким образом память не возвращается в систему.
-121--4667618-

Ваше решение работает. Единственным другим подходом была бы сериализация карты самостоятельно (итерация над ключами и значениями). Это означает, что вы должны быть уверены, что все случаи обработаны правильно (например, если вы передаете значения как key = value , вы должны найти способ разрешить = в ключе/value и вы должны разделить пары каким-либо образом, что означает, что вы также должны разрешить этот символ разделения в имени и т.д.).

В целом, это трудно получить правильно, легко получить неправильно и будет принимать гораздо больше кода и головной боли. Кроме того, не забывайте, что вам придется написать много кода обработки ошибок в анализаторе (на стороне приемника).

1
ответ дан 6 December 2019 в 12:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: