Хэш json и сравнение в Java

Я делаю некоторую миграцию и хотел бы сравнить запросы JSON, отправляемые на новую и старую службу. У меня есть некоторые конфиденциальные данные в моем JSON, поэтому я не хочу регистрировать их напрямую, я хочу хэшировать, а затем регистрировать их. После хеширования я хочу сравнить хэши.

PS: у меня есть сложные строки JSON

{'method': 'do.stuff', 'params': ['asdf', 3, {'foo': 'bar'}]}

а также

{'params': ['asdf', 3, {'foo': 'bar'}], 'method': 'do.stuff'}

Должен возвращать один и тот же хеш независимо от порядка

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
745
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Один из способов сделать это — отсортировать ключи каждого объекта, чтобы JSON был в том же порядке, а затем создать хэш. Вам также нужно позаботиться о вложенных объектах и ​​массивах.

Например...

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.util.DigestUtils;

import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class JsonHash {

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();

        String jsonStringA = "{\"a\": \"100\", \"b\": \"200\", \"c\": [{\"d\": 200, \"e\": 100}], \"p\": null}";
        String jsonStringB = "{\"p\": null, \"b\": \"200\", \"a\": \"100\", \"c\": [{\"e\": 100, \"d\": 200}]}";
        String jsonStringC = "{\"p\": 1, \"b\": \"200\", \"a\": \"100\", \"c\": [{\"e\": 100, \"d\": 200}]}";

        String hashA = getHash(mapper, jsonStringA);
        String hashB = getHash(mapper, jsonStringB);
        String hashC = getHash(mapper, jsonStringC);

        System.out.println(hashA);
        System.out.println(hashB);
        System.out.println(hashC);
    }

    private static String getHash(ObjectMapper mapper, String jsonStringA) throws IOException {
        JsonNode jsonNode = mapper.readTree(jsonStringA);
        Map map = mapper.convertValue(jsonNode, Map.class);
        TreeMap sorted = sort(map);
        String s = mapper.writeValueAsString(sorted);
        byte[] md5Digest = DigestUtils.md5Digest(s.getBytes());
        return DatatypeConverter.printHexBinary(md5Digest).toUpperCase();
    }

    private static TreeMap sort(Map map) {
        TreeMap result = new TreeMap();
        map.forEach((k, v) -> {
            if (v != null) {
                if (v instanceof Map) {
                    result.put(k, sort((Map) v));
                } else if (v instanceof List) {
                    result.put(k, copyArray((List) v));
                } else {
                    result.put(k, v);
                }
            } else {
               result.put(k, null);
            }
        });
        return result;
    }

    private static List copyArray(List v) {
        List result = new ArrayList(v.size());

        for (int i = 0; i < v.size(); i++) {
            Object element = v.get(i);

            if (element != null) {
                if (element instanceof Map) {
                    result.add(sort((Map) element));
                } else if (element instanceof List) {
                    result.add(copyArray((List) element));
                } else {
                    result.add(element);
                }
            } else {
                result.add(null);
            }
        }

        return result;
    }
}

Выход:

FADE525B0423415184D913299E90D959
FADE525B0423415184D913299E90D959
B49993CB657F1C9A62A339E5482F93D1

Хэш ваших примеров получается как 3EBAD6BDF5064304B3DD499BDAF0E635.

Другие вопросы по теме