#!/usr/bin/env python # vim: set fileencoding=utf-8 : ############################################################################### # # # Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ # # Contact: beat.support@idiap.ch # # # # This file is part of the beat.backend.python module of the BEAT platform. # # # # Commercial License Usage # # Licensees holding valid commercial BEAT licenses may use this file in # # accordance with the terms contained in a written agreement between you # # and Idiap. For further information contact tto@idiap.ch # # # # Alternatively, this file may be used under the terms of the GNU Affero # # Public License version 3 as published by the Free Software and appearing # # in the file LICENSE.AGPL included in the packaging of this file. # # The BEAT platform is distributed in the hope that it will be useful, but # # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # # or FITNESS FOR A PARTICULAR PURPOSE. # # # # You should have received a copy of the GNU Affero Public License along # # with the BEAT platform. If not, see http://www.gnu.org/licenses/. # # # ############################################################################### """Various functions for hashing platform contributions and others""" import hashlib import simplejson import collections import copy import six def _sha256(s): """A python2/3 replacement for :py:func:`haslib.sha256`""" try: if isinstance(s, str): s = six.u(s) return hashlib.sha256(s.encode('utf8')).hexdigest() except: return hashlib.sha256(s).hexdigest() def _stringify(dictionary): names = sorted(dictionary.keys()) converted_dictionary = '{' for name in names: converted_dictionary += '"%s":%s,' % (name, str(dictionary[name])) if len(converted_dictionary) > 1: converted_dictionary = converted_dictionary[:-1] converted_dictionary += '}' return converted_dictionary def hash(dictionary_or_string): if isinstance(dictionary_or_string, dict): return _sha256(_stringify(dictionary_or_string)) else: return _sha256(dictionary_or_string) def hashJSON(contents, description): """Hashes the pre-loaded JSON object using :py:func:`hashlib.sha256` Excludes description changes """ if description in contents: contents = copy.deepcopy(contents) #temporary copy del contents[description] contents = simplejson.dumps(contents, sort_keys=True) return hashlib.sha256(contents).hexdigest() def hashJSONFile(path, description): """Hashes the JSON file contents using :py:func:`hashlib.sha256` Excludes description changes """ try: with open(path, 'rb') as f: return hashJSON(simplejson.load(f, object_pairs_hook=collections.OrderedDict), description) #preserve order except simplejson.JSONDecodeError: # falls back to normal file content hashing return hashFileContents(path) def hashFileContents(path): """Hashes the file contents using :py:func:`hashlib.sha256`.""" with open(path, 'rb') as f: return hashlib.sha256(f.read()).hexdigest()