ssdeep-3.1/0000755000175000017500000000000012370752033013066 5ustar phibophibo00000000000000ssdeep-3.1/setup.cfg0000644000175000017500000000007312370752033014707 0ustar phibophibo00000000000000[egg_info] tag_build = tag_svn_revision = 0 tag_date = 0 ssdeep-3.1/PKG-INFO0000644000175000017500000000671412370752033014173 0ustar phibophibo00000000000000Metadata-Version: 1.1 Name: ssdeep Version: 3.1 Summary: Python wrapper for the ssdeep library Home-page: http://github.com/DinoTools/python-ssdeep Author: PhiBo (DinoTools) Author-email: UNKNOWN License: LGPLv3+ Description: ssdeep Python Wrapper ===================== This is a straightforward Python wrapper for `ssdeep by Jesse Kornblum`_, which is a library for computing context triggered piecewise hashes (CTPH). Also called fuzzy hashes, CTPH can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length. .. image:: https://pypip.in/version/ssdeep/badge.svg :target: https://pypi.python.org/pypi/ssdeep/ :alt: Latest Version .. image:: https://pypip.in/license/ssdeep/badge.svg :target: https://pypi.python.org/pypi/ssdeep/ :alt: License .. image:: https://travis-ci.org/DinoTools/python-ssdeep.svg?branch=master :target: https://travis-ci.org/DinoTools/python-ssdeep How to use it ============= To compute a fuzzy hash, use ``hash`` function: .. code-block:: pycon >>> import ssdeep >>> hash1 = ssdeep.hash('Also called fuzzy hashes, Ctph can match inputs that have homologies.') >>> hash1 '3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C' >>> hash2 = ssdeep.hash('Also called fuzzy hashes, CTPH can match inputs that have homologies.') >>> hash2 '3:AXGBicFlIHBGcL6wCrFQEv:AXGH6xLsr2C' The ``compare`` function returns the match between 2 hashes, an integer value from 0 (no match) to 100. .. code-block:: pycon >>> ssdeep.compare(hash1, hash2) 22 More examples are available in the `python-ssdeep documentation`_. Install ======= If all requirements are met it is possible to install the wrapper by using pip or easy_install. .. code-block:: console $ pip install ssdeep For more information have a look at the `python-ssdeep documentation`_. Licensing ========= The code is licensed under the terms of the LGPLv3+. This wrapper includes the unchanged source distribution of `ssdeep version 2.10`_. It is licensed under the GPLv2. .. _ssdeep by Jesse Kornblum: http://ssdeep.sourceforge.net/ .. _ssdeep version 2.10: http://ssdeep.sourceforge.net/changes.txt .. _python-ssdeep documentation: http://python-ssdeep.readthedocs.org Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+) Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Topic :: Software Development :: Libraries :: Python Modules ssdeep-3.1/setup.py0000755000175000017500000000647112370752012014610 0ustar phibophibo00000000000000#!/usr/bin/env python import glob import os import stat import subprocess import sys from distutils.command.build import build from setuptools import setup, find_packages from setuptools.command.install import install base_dir = os.path.dirname(__file__) use_system_lib = True if os.environ.get("BUILD_LIB") == "1": use_system_lib = False class CFFIBuild(build): def finalize_options(self): self.distribution.ext_modules = get_ext_modules() build.finalize_options(self) class CFFIInstall(install): def finalize_options(self): self.distribution.ext_modules = get_ext_modules() install.finalize_options(self) def build_ssdeep(): try: os.chmod( "ssdeep-lib/configure", stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO ) except: pass returncode = subprocess.call( "(cd ssdeep-lib && ./configure && make)", shell=True ) if returncode == 0: return print("Failed while building ssdeep lib with configure and make.") print("Retry with autoreconf ...") returncode = subprocess.call( "(cd ssdeep-lib && autoreconf --force && ./configure && make)", shell=True ) if returncode != 0: sys.exit("Failed while building ssdeep lib.") def get_ext_modules(): from ssdeep.binding import Binding if use_system_lib: binding = Binding() else: build_ssdeep() binding = Binding( extra_objects=get_objects(), include_dirs=["./ssdeep-lib/"], libraries=[] ) binding.verify() ext_modules = [ binding.ffi.verifier.get_extension() ] return ext_modules def get_objects(): objects = glob.glob("ssdeep-lib/.libs/*.o") if len(objects) > 0: return objects return glob.glob("ssdeep-lib/.libs/*.obj") about = {} with open(os.path.join(base_dir, "ssdeep", "__about__.py")) as f: exec(f.read(), about) with open(os.path.join(base_dir, "README.rst")) as f: long_description = f.read() setup( name=about["__title__"], version=about["__version__"], description=about["__summary__"], long_description=long_description, license=about["__license__"], url=about["__uri__"], zip_safe=False, author=about["__author__"], classifiers=[ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Topic :: Software Development :: Libraries :: Python Modules", ], install_requires=[ # ToDo: set min version "cffi", "six >= 1.4.1" ], setup_requires=[ # ToDo: set min version "cffi", "six >= 1.4.1" ], packages=find_packages(exclude=["*.tests", "*.tests.*"]), include_package_data=True, cmdclass={ "build": CFFIBuild, "install": CFFIInstall, }, ext_package="ssdeep", ) ssdeep-3.1/README.rst0000644000175000017500000000410612370752012014553 0ustar phibophibo00000000000000ssdeep Python Wrapper ===================== This is a straightforward Python wrapper for `ssdeep by Jesse Kornblum`_, which is a library for computing context triggered piecewise hashes (CTPH). Also called fuzzy hashes, CTPH can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length. .. image:: https://pypip.in/version/ssdeep/badge.svg :target: https://pypi.python.org/pypi/ssdeep/ :alt: Latest Version .. image:: https://pypip.in/license/ssdeep/badge.svg :target: https://pypi.python.org/pypi/ssdeep/ :alt: License .. image:: https://travis-ci.org/DinoTools/python-ssdeep.svg?branch=master :target: https://travis-ci.org/DinoTools/python-ssdeep How to use it ============= To compute a fuzzy hash, use ``hash`` function: .. code-block:: pycon >>> import ssdeep >>> hash1 = ssdeep.hash('Also called fuzzy hashes, Ctph can match inputs that have homologies.') >>> hash1 '3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C' >>> hash2 = ssdeep.hash('Also called fuzzy hashes, CTPH can match inputs that have homologies.') >>> hash2 '3:AXGBicFlIHBGcL6wCrFQEv:AXGH6xLsr2C' The ``compare`` function returns the match between 2 hashes, an integer value from 0 (no match) to 100. .. code-block:: pycon >>> ssdeep.compare(hash1, hash2) 22 More examples are available in the `python-ssdeep documentation`_. Install ======= If all requirements are met it is possible to install the wrapper by using pip or easy_install. .. code-block:: console $ pip install ssdeep For more information have a look at the `python-ssdeep documentation`_. Licensing ========= The code is licensed under the terms of the LGPLv3+. This wrapper includes the unchanged source distribution of `ssdeep version 2.10`_. It is licensed under the GPLv2. .. _ssdeep by Jesse Kornblum: http://ssdeep.sourceforge.net/ .. _ssdeep version 2.10: http://ssdeep.sourceforge.net/changes.txt .. _python-ssdeep documentation: http://python-ssdeep.readthedocs.org ssdeep-3.1/MANIFEST.in0000644000175000017500000000047312370752012014625 0ustar phibophibo00000000000000include README.rst CHANGELOG.rst recursive-include ssdeep-lib *.c *.cpp *.h Makefile.am install-sh config.guess COPYING Makefile.in ssdeep.1 configure README depcomp NEWS TODO config.sub FILEFORMAT missing configure.ac config.h.in aclocal.m4 AUTHORS INSTALL ltmain.sh ChangeLog compile recursive-include tests *.py ssdeep-3.1/CHANGELOG.rst0000644000175000017500000000117612370752012015111 0ustar phibophibo00000000000000Changelog ========= 3.1 - 2014-08-07 ~~~~~~~~~~~~~~~~ * Fix build issue with ssdeep < 2.10 3.0 - 2014-06-25 ~~~~~~~~~~~~~~~~ * Completely rewritten to use CFFI * Interface in the spirit of hashlib * Use pytest and tox for tests * Use installed fuzzy lib by default 2.9-0.3 - 2013-03-12 ~~~~~~~~~~~~~~~~~~~~ * Fix build issue with Python 2.6 2.9-0.2 - 2012-10-11 ~~~~~~~~~~~~~~~~~~~~ * Fixing small bug in setup.py 2.9-0.1 - 2012-08-01 ~~~~~~~~~~~~~~~~~~~~ * Updated ssdeep from 2.5 to 2.9 * Added Python 3.x support 2.5 - 2010-09-03 ~~~~~~~~~~~~~~~~ * Initial release .. _`master`: https://github.com/DinoTools/python-ssdeep ssdeep-3.1/tests/0000755000175000017500000000000012370752033014230 5ustar phibophibo00000000000000ssdeep-3.1/tests/test_lib.py0000755000175000017500000000563312370752012016416 0ustar phibophibo00000000000000#!/usr/bin/env python import pytest import ssdeep class TestFunctionsFail(object): def test_compare(self): with pytest.raises(TypeError): ssdeep.compare( "3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C", None ) with pytest.raises(TypeError): ssdeep.compare( None, "3:AXGBicFlIHBGcL6wCrFQEv:AXGH6xLsr2C" ) with pytest.raises(ssdeep.InternalError): ssdeep.compare( "3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C", "" ) def test_hash(self): with pytest.raises(TypeError): ssdeep.hash(None) with pytest.raises(TypeError): ssdeep.hash(1234) class TestFunctions(object): def test_compare(self): res = ssdeep.compare( "3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C", "3:AXGBicFlIHBGcL6wCrFQEv:AXGH6xLsr2C" ) assert res == 22 res = ssdeep.compare( b"3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C", b"3:AXGBicFlIHBGcL6wCrFQEv:AXGH6xLsr2C" ) assert res == 22 def test_hash_1(self): res = ssdeep.hash("Also called fuzzy hashes, Ctph can match inputs that have homologies.") assert res == "3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C" def test_hash_2(self): res = ssdeep.hash("Also called fuzzy hashes, CTPH can match inputs that have homologies.") assert res == "3:AXGBicFlIHBGcL6wCrFQEv:AXGH6xLsr2C" def test_hash_3(self): res = ssdeep.hash(b"Also called fuzzy hashes, CTPH can match inputs that have homologies.") assert res == "3:AXGBicFlIHBGcL6wCrFQEv:AXGH6xLsr2C" def test_hash_from_file(self): with pytest.raises(IOError): ssdeep.hash_from_file("tests/files/") with pytest.raises(IOError): ssdeep.hash_from_file("tests/files/file-does-not-exist.txt") res = ssdeep.hash_from_file("tests/files/file.txt") assert res == "3:AXGBicFlgVNhBGcL6wCrFQE3:AXGHsNhxLsr2s" class TestHashClass(object): def test_update(self): obj = ssdeep.Hash() obj.update("Also called fuzzy hashes, Ctph can match inputs that have homologies.") res = obj.digest() assert res == "3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C" class TestPseudoHashClass(object): def test_update(self): obj = ssdeep.PseudoHash() obj.update("Also called fuzzy hashes, ") obj.update("Ctph can match inputs that have homologies.") res = obj.digest() assert res == "3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C" class TestHashClassFail(object): def test_update_01(self): obj = ssdeep.Hash() with pytest.raises(TypeError): obj.update(None) def test_update_02(self): obj = ssdeep.Hash() with pytest.raises(TypeError): obj.update(1234) ssdeep-3.1/ssdeep.egg-info/0000755000175000017500000000000012370752033016043 5ustar phibophibo00000000000000ssdeep-3.1/ssdeep.egg-info/requires.txt0000644000175000017500000000002212370752032020434 0ustar phibophibo00000000000000cffi six >= 1.4.1 ssdeep-3.1/ssdeep.egg-info/not-zip-safe0000644000175000017500000000000112370752032020270 0ustar phibophibo00000000000000 ssdeep-3.1/ssdeep.egg-info/dependency_links.txt0000644000175000017500000000000112370752032022110 0ustar phibophibo00000000000000 ssdeep-3.1/ssdeep.egg-info/PKG-INFO0000644000175000017500000000671412370752032017147 0ustar phibophibo00000000000000Metadata-Version: 1.1 Name: ssdeep Version: 3.1 Summary: Python wrapper for the ssdeep library Home-page: http://github.com/DinoTools/python-ssdeep Author: PhiBo (DinoTools) Author-email: UNKNOWN License: LGPLv3+ Description: ssdeep Python Wrapper ===================== This is a straightforward Python wrapper for `ssdeep by Jesse Kornblum`_, which is a library for computing context triggered piecewise hashes (CTPH). Also called fuzzy hashes, CTPH can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length. .. image:: https://pypip.in/version/ssdeep/badge.svg :target: https://pypi.python.org/pypi/ssdeep/ :alt: Latest Version .. image:: https://pypip.in/license/ssdeep/badge.svg :target: https://pypi.python.org/pypi/ssdeep/ :alt: License .. image:: https://travis-ci.org/DinoTools/python-ssdeep.svg?branch=master :target: https://travis-ci.org/DinoTools/python-ssdeep How to use it ============= To compute a fuzzy hash, use ``hash`` function: .. code-block:: pycon >>> import ssdeep >>> hash1 = ssdeep.hash('Also called fuzzy hashes, Ctph can match inputs that have homologies.') >>> hash1 '3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C' >>> hash2 = ssdeep.hash('Also called fuzzy hashes, CTPH can match inputs that have homologies.') >>> hash2 '3:AXGBicFlIHBGcL6wCrFQEv:AXGH6xLsr2C' The ``compare`` function returns the match between 2 hashes, an integer value from 0 (no match) to 100. .. code-block:: pycon >>> ssdeep.compare(hash1, hash2) 22 More examples are available in the `python-ssdeep documentation`_. Install ======= If all requirements are met it is possible to install the wrapper by using pip or easy_install. .. code-block:: console $ pip install ssdeep For more information have a look at the `python-ssdeep documentation`_. Licensing ========= The code is licensed under the terms of the LGPLv3+. This wrapper includes the unchanged source distribution of `ssdeep version 2.10`_. It is licensed under the GPLv2. .. _ssdeep by Jesse Kornblum: http://ssdeep.sourceforge.net/ .. _ssdeep version 2.10: http://ssdeep.sourceforge.net/changes.txt .. _python-ssdeep documentation: http://python-ssdeep.readthedocs.org Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+) Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Topic :: Software Development :: Libraries :: Python Modules ssdeep-3.1/ssdeep/0000755000175000017500000000000012370752033014351 5ustar phibophibo00000000000000ssdeep-3.1/ssdeep/binding.py0000644000175000017500000000653112370752012016337 0ustar phibophibo00000000000000import binascii from cffi import FFI from ssdeep.__about__ import __version__ cdef = """ static const long FUZZY_FLAG_ELIMSEQ; static const long FUZZY_FLAG_NOTRUNC; static const long FUZZY_MAX_RESULT; struct fuzzy_state; struct fuzzy_state *fuzzy_new(void); int fuzzy_update( struct fuzzy_state *, const unsigned char *, size_t ); int fuzzy_digest( const struct fuzzy_state *, char *, unsigned int ); void fuzzy_free(struct fuzzy_state *); int fuzzy_hash_buf( const unsigned char *, uint32_t, char * ); int fuzzy_hash_file( FILE *, char * ); int fuzzy_hash_stream( FILE *, char * ); int fuzzy_hash_filename( const char *, char * ); int fuzzy_compare( const char *, const char * ); static const long ssdeep_HAS_STATEFUL_HASHING; """ source = """ #include "fuzzy.h" #ifndef FUZZY_FLAG_ELIMSEQ static const long ssdeep_HAS_STATEFUL_HASHING = 0; struct fuzzy_state {}; const long FUZZY_FLAG_ELIMSEQ = 0; const long FUZZY_FLAG_NOTRUNC = 0; int (*fuzzy_digest)( const struct fuzzy_state *, char *, unsigned int ) = NULL; int (*fuzzy_free)(struct fuzzy_state *) = NULL; int (*fuzzy_new)(void) = NULL; int (*fuzzy_update)( struct fuzzy_state *, const unsigned char *, size_t ) = NULL; int (*fuzzy_hash_stream)( FILE *, char * ) = NULL; #else static const long ssdeep_HAS_STATEFUL_HASHING = 1; #endif """ CONDITIONAL_NAMES = { "ssdeep_HAS_STATEFUL_HASHING": ( "FUZZY_FLAG_ELIMSEQ", "FUZZY_FLAG_NOTRUNC", "fuzzy_digest", "fuzzy_free", "fuzzy_new", "fuzzy_update", "fuzzy_hash_stream" ) } class Binding(object): def __init__(self, extra_objects=None, include_dirs=None, libraries=None): self.ffi = FFI() self.ffi.cdef(cdef) self._lib = None if extra_objects is None: extra_objects = [] self._extra_objects = extra_objects if include_dirs is None: include_dirs = [] self._include_dirs = include_dirs if libraries is None: libraries = ["fuzzy"] self._libraries = libraries def verify(self): self._lib = self.ffi.verify( source, ext_package="ssdeep", extra_objects=self._extra_objects, include_dirs=self._include_dirs, modulename=_create_modulename(cdef, source, __version__), libraries=self._libraries, ) for condition, names in CONDITIONAL_NAMES.items(): if getattr(self._lib, condition): continue for name in names: delattr(self._lib, name) @property def lib(self): if self._lib is None: self.verify() return self._lib def _create_modulename(cdef, source, sys_version): key = "\x00".join([sys_version[:3], source, cdef]) key = key.encode("utf-8") k1 = hex(binascii.crc32(key[0::2]) & 0xffffffff) k1 = k1.lstrip("0x").rstrip("L") k2 = hex(binascii.crc32(key[1::2]) & 0xffffffff) k2 = k2.lstrip("0").rstrip("L") return "_ssdeep_cffi_{0}{1}".format(k1, k2) ssdeep-3.1/ssdeep/__init__.py0000644000175000017500000001625612370752012016471 0ustar phibophibo00000000000000""" This is a straightforward Python wrapper for ssdeep by Jesse Kornblum, which is a library for computing Context Triggered Piecewise Hashes (CTPH). """ import os import six from ssdeep.__about__ import ( __author__, __copyright__, __email__, __license__, __summary__, __title__, __uri__, __version__ ) from ssdeep.binding import Binding binding = Binding() ffi = binding.ffi class BaseError(Exception): """The base for all other Exceptions""" pass class InternalError(BaseError): """Raised if lib returns internal error""" pass class Hash(object): """ Hashlib like object. It is only supported with ssdeep/libfuzzy >= 2.10. :raises InternalError: If lib returns internal error :raises NotImplementedError: Required functions are not available """ def __init__(self): self._state = ffi.NULL if not hasattr(binding.lib, "fuzzy_new"): raise NotImplementedError("Only supported with ssdeep >= 2.10") self._state = binding.lib.fuzzy_new() if self._state == ffi.NULL: raise InternalError("Unable to create state object") def update(self, buf, encoding="utf-8"): """ Feed the data contained in the given buffer to the state. :param String|Byte buf: The data to be hashed :param String encoding: Encoding is used if buf is String :raises InternalError: If lib returns an internal error :raises TypeError: If buf is not Bytes, String or Unicode """ if self._state == ffi.NULL: raise InternalError("State object is NULL") if isinstance(buf, six.text_type): buf = buf.encode(encoding) if not isinstance(buf, six.binary_type): raise TypeError( "Argument must be of string, unicode or bytes type not " "'%r'" % type(buf) ) if binding.lib.fuzzy_update(self._state, buf, len(buf)) != 0: binding.lib.fuzzy_free(self._state) raise InternalError("Invalid state object") def digest(self, elimseq=False, notrunc=False): """ Obtain the fuzzy hash. This operation does not change the state at all. It reports the hash for the concatenation of the data previously fed using update(). :return: The fuzzy hash :rtype: String :raises InternalError: If lib returns an internal error """ if self._state == ffi.NULL: raise InternalError("State object is NULL") flags = (binding.lib.FUZZY_FLAG_ELIMSEQ if elimseq else 0) | \ (binding.lib.FUZZY_FLAG_NOTRUNC if notrunc else 0) result = ffi.new("char[]", binding.lib.FUZZY_MAX_RESULT) if binding.lib.fuzzy_digest(self._state, result, flags) != 0: raise InternalError("Function returned an unexpected error code") return ffi.string(result).decode("ascii") def __del__(self): if self._state != ffi.NULL: binding.lib.fuzzy_free(self._state) class PseudoHash(object): """ Hashlib like object. Use this class only if Hash() isn't supported by your ssdeep/libfuzzy library. This class stores the provided data in memory, so be careful when hashing large files. """ def __init__(self): self._data = b"" def update(self, buf, encoding="utf-8"): """ Feed the data contained in the given buffer to the state. :param String|Byte buf: The data to be hashed :param String encoding: Encoding is used if buf is String :raises TypeError: If buf is not Bytes, String or Unicode """ if isinstance(buf, six.text_type): buf = buf.encode(encoding) if not isinstance(buf, six.binary_type): raise TypeError( "Argument must be of string, unicode or bytes type not " "'%r'" % type(buf) ) self._data = self._data + buf def digest(self, elimseq=False, notrunc=False): """ Obtain the fuzzy hash. This operation does not change the state at all. It reports the hash for the concatenation of the data previously fed using update(). :return: The fuzzy hash :rtype: String """ return hash(self._data) def compare(sig1, sig2): """ Computes the match score between two fuzzy hash signatures. Returns a value from zero to 100 indicating the match score of the two signatures. A match score of zero indicates the signatures did not match. :param Bytes|String sig1: First fuzzy hash signature :param Bytes|String sig2: Second fuzzy hash signature :return: Match score (0-100) :rtype: Integer :raises InternalError: If lib returns an internal error :raises TypeError: If sig is not String, Unicode or Bytes """ if isinstance(sig1, six.text_type): sig1 = sig1.encode("ascii") if isinstance(sig2, six.text_type): sig2 = sig2.encode("ascii") if not isinstance(sig1, six.binary_type): raise TypeError( "First argument must be of string, unicode or bytes type not " "'%s'" % type(sig1) ) if not isinstance(sig2, six.binary_type): raise TypeError( "Second argument must be of string, unicode or bytes type not " "'%r'" % type(sig2) ) res = binding.lib.fuzzy_compare(sig1, sig2) if res < 0: raise InternalError("Function returned an unexpected error code") return res def hash(buf, encoding="utf-8"): """ Compute the fuzzy hash of a buffer :param String|Bytes buf: The data to be fuzzy hashed :return: The fuzzy hash :rtype: String :raises InternalError: If lib returns an internal error :raises TypeError: If buf is not String or Bytes """ if isinstance(buf, six.text_type): buf = buf.encode(encoding) if not isinstance(buf, six.binary_type): raise TypeError( "Argument must be of string, unicode or bytes type not " "'%r'" % type(buf) ) # allocate memory for result result = ffi.new("char[]", binding.lib.FUZZY_MAX_RESULT) if binding.lib.fuzzy_hash_buf(buf, len(buf), result) != 0: raise InternalError("Function returned an unexpected error code") return ffi.string(result).decode("ascii") def hash_from_file(filename): """ Compute the fuzzy hash of a file. Opens, reads, and hashes the contents of the file 'filename' :param String|Bytes filename: The name of the file to be hashed :return: The fuzzy hash of the file :rtype: String :raises IOError: If Python is unable to read the file :raises InternalError: If lib returns an internal error """ if not os.path.exists(filename): raise IOError("Path not found") if not os.path.isfile(filename): raise IOError("File not found") if not os.access(filename, os.R_OK): raise IOError("File is not readable") result = ffi.new("char[]", binding.lib.FUZZY_MAX_RESULT) if binding.lib.fuzzy_hash_filename(filename.encode("utf-8"), result) != 0: raise InternalError("Function returned an unexpected error code") return ffi.string(result).decode("ascii") ssdeep-3.1/ssdeep/__about__.py0000644000175000017500000000066112370752012016631 0ustar phibophibo00000000000000__all__ = [ "__author__", "__copyright__", "__email__", "__license__", "__summary__", "__title__", "__uri__", "__version__", ] __title__ = "ssdeep" __summary__ = "Python wrapper for the ssdeep library" __uri__ = "http://github.com/DinoTools/python-ssdeep" __version__ = "3.1" __author__ = "PhiBo (DinoTools)" __email__ = "" __license__ = "LGPLv3+" __copyright__ = "Copyright 2014 %s" % __author__