diff options
author | toonn <toonn@toonn.io> | 2020-07-07 22:53:57 +0200 |
---|---|---|
committer | toonn <toonn@toonn.io> | 2020-07-07 23:02:25 +0200 |
commit | f321ce4c2072d1e76bbef7f85764c25ef7102f67 (patch) | |
tree | 9e054c0e7bd31a107a65cadfa5634073eac98a40 | |
parent | 10894de1ff5baf71151859f1a3d864997202b1a7 (diff) | |
download | ranger-f321ce4c2072d1e76bbef7f85764c25ef7102f67.tar.gz |
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.
-rw-r--r-- | ranger/core/actions.py | 12 |
1 files 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('<lLd', stat_.st_dev, stat_.st_ino, stat_.st_mtime)) return '{0}.jpg'.format(sha.hexdigest()) def get_preview(self, fobj, width, height): # pylint: disable=too-many-return-statements |