From f321ce4c2072d1e76bbef7f85764c25ef7102f67 Mon Sep 17 00:00:00 2001 From: toonn Date: Tue, 7 Jul 2020 22:53:57 +0200 Subject: Switch to packing fields for sha512_encode The easy solution was to render the `st_dev, st_ino, st_mtime` to a string and encode that before hashing. This solution is more efficient because it packs the numbers as bytes rather than the digits. Technically POSIX.1 does not specify an upper limit on the sizes for these fields. I think it's safe to say none of the major operating systems will use more than 8 bytes/64 bits any time soon. --- ranger/core/actions.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 91f94f77..e76adc87 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -17,6 +17,7 @@ import tempfile from inspect import cleandoc from stat import S_IEXEC from hashlib import sha512 +from struct import pack from logging import getLogger import ranger @@ -1049,11 +1050,12 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m @staticmethod def sha512_encode(path): stat_ = stat(path) - sha = sha512( - '{dev},{inode},{mtime}'.format( - dev=stat_.st_dev, inode=stat_.st_ino, mtime=stat_.st_mtime - ).encode('utf-8', 'backslashreplace') - ) + # How I arrived at the pack format string: + # < -> little-endian + # l -> st_dev: signed int (32/64 bits depending on platform) + # L -> st_ino: unsigned int (ditto) + # d -> st_mtime: double in python + sha = sha512(pack('