Расчет SHA для постоянной структуры данных - PullRequest
1 голос
/ 02 апреля 2020

Существует ли библиотека для вычисления какого-либо SHA для постоянных структур данных?

(sha (pr-str <datastructure>)) не работает, потому что иногда порядок клавиш при печати не совпадает.

Ответы [ 4 ]

2 голосов
/ 02 апреля 2020

Хотя это не криптографическая функция c, clojure.core/hash-unordered-coll даст вам постоянное значение ha sh, если коллекции имеют одинаковое содержимое, и, возможно, вы можете использовать это:

user=> (hash-unordered-coll (sorted-map :b 2 :a 1))
161871944
user=> (hash-unordered-coll {:b 2, :a 1})
161871944
user=> (hash-unordered-coll [[:b 2] [:a 1]])
161871944

См. https://clojuredocs.org/clojure.core/hash-unordered-coll

1 голос
/ 02 апреля 2020

Функция tupelo.lexical / compare-generi c реализует компаратор, который безопасно использовать для различных типов. Вы можете объединить это с sorted-map-by и sorted-set-by, чтобы преобразовать все карты / наборы в стабильные версии, которые всегда печатаются в одном и том же порядке. Тогда сработает метод (sha (pr-str XXX)).

Вышеприведенные логики c уже доступны в функции tupelo.core / unlazy . Функция tupelo.misc / str-> sha также делает то, что говорит на жестяной банке. Итак, теперь окончательным решением становится:

(ns demo.core
  (:require 
    [tupelo.core :as t]
    [tupelo.misc :as tm] ))

(tm/str->sha (pr-str (t/unlazy XXX)))

, где XXX - любая коллекция Clojure. Демо-код:

(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:require
    [tupelo.core :as t]
    [tupelo.misc :as tm]))

(dotest
  (let [stuff     {:hello     "there"
                   1          [2 3 4]
                   "gooodbye" #{"cruel" :world}
                   'forever   ['and "ever" :and #{"ever" 'more}]}
        stuff-str (pr-str (t/unlazy stuff))
        stuff-sha (tm/str->sha (pr-str (t/unlazy stuff)))]
    (is= stuff-str
      "{:hello \"there\", forever [and \"ever\" :and #{more \"ever\"}], 1 [2 3 4], \"gooodbye\" #{:world \"cruel\"}}")
    (is= stuff-sha "af3ade069e7a33139f5ee1fd1d35fd82807e3b1c")))
1 голос
/ 02 апреля 2020

Я нашел с помощью поиска Google следующий вопрос и обсуждение того, существует ли криптографически надежный способ объединения криптостойких значений ha sh элементов неупорядоченного набора в криптостойкий га sh для всего установить, игнорируя порядок. В одном ответе утверждается, что сортировка значений ha sh элементов в одну строку битов с последующим вычислением криптостойкого ha sh на этой строке должна быть надежной. XOR или добавление хэшей элементов вместе не является. Я не прочитал все ответы, поэтому могут быть известны лучшие подходы: https://crypto.stackexchange.com/questions/54544/how-to-to-calculate-the-hash-of-an-unordered-set

1 голос
/ 02 апреля 2020

Это действительно зависит от того, для чего вы этого хотите. Для простейших вариантов использования, clojure.core/hash хорошо. Но поскольку «структура данных» является гораздо более сложным форматом ввода, чем «последовательность байтов», нет очевидной универсальной концепции отпечатка пальца - вам нужно решить, какие функции ему нужны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...