On 23/02/17 13:36, Gerd v. Egidy wrote: > So I think that this would move the bar for a possible user of paperbackup.py > higher than I want to.
Yes, it should be easy to use. In fact, I've sometimes heard the complaint that "paperkey is not easy to install and/or use". That's really too bad that those people feel that way. > Ideally it is a tool or combination of tools already deployed widely, like > sed > and sort I used in paperrestore. This would make the checksums still usable > even when the source to paperbackup.py isn't available anymore. It took me some fiddling... but using CRC RevEng[1] I got a checksum in Python that is compatible to POSIX cksum. The following Python: >>> from posixcksum import PosixCkSum >>> from base64 import b64encode >>> crc, _ = PosixCkSum.sum_whole(bytearray(b'123456789')) >>> b64encode(crc.to_bytes(4,byteorder='big'))[:4] b'N3pg' generates the same checksums as the following Bash code: $ printf $(printf '%08x' $(echo -n 123456789 | cksum | cut -d' ' -f1) | sed 's/../\\x\0/g')|base64|cut -b-4 N3pg This is done with the attached Python code. It is written for compactness rather than speed. Just re-implementing the crc function would probably be quicker. HTH, Peter. [1] <http://reveng.sourceforge.net/> -- I use the GNU Privacy Guard (GnuPG) in combination with Enigmail. You can send me encrypted mail if you want some privacy. My key is available at <http://digitalbrains.com/2012/openpgp-key-peter>
#!/usr/bin/python3 # Copyright (c) 2017 Peter Lebbing <pe...@digitalbrains.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. import binascii class PosixCkSum(object): """Create a POSIX cksum-compliant checksum.""" def __init__(self): """Create new checksumming instance.""" self.n = 0 self.crc = 0xffffffff def sum(self, bs): """Checksum another part of data. IMPORTANT: the data in bs is DESTROYED. """ self.bit_reverse(bs) self.crc = binascii.crc32(bs, self.crc) self.n += len(bs) def finish(self): """Finish checksum computation and return result. After this, the object should no longer be used. """ if not self.n: return self.crc, self.n bs = bytearray(self.n.to_bytes((self.n.bit_length() + 7) // 8, byteorder='little')) self.bit_reverse(bs) self.crc = binascii.crc32(bs, self.crc) crcb = bytearray(self.crc.to_bytes(4, byteorder='little')) self.bit_reverse(crcb) crc = int.from_bytes(crcb, byteorder='big') return crc, self.n @classmethod def sum_whole(cls, bs): """Checksum a single piece of data. IMPORTANT: the data in bs is DESTROYED. """ c = cls() c.sum(bs) return c.finish() @staticmethod def bit_reverse(bs): """Reverse the bits in every byte of the argument in-place""" for i,b in enumerate(bs): r = 0 t = 0x80 s = 0x01 while t: if (b & t): r |= s t >>= 1; s <<= 1; bs[i] = r if __name__ == '__main__': # Checksum all files passed as arguments, or stdin if none from sys import argv,stdin if len(argv) == 1: bs = bytearray(stdin.buffer.read()) crc, n = PosixCkSum.sum_whole(bs) print(crc, n) else: for fn in argv[1:]: if fn == '-': bs = bytearray(stdin.buffer.read()) else: with open(fn, 'rb') as f: bs = bytearray(f.read()) crc, n = PosixCkSum.sum_whole(bs) print(crc, n, fn)
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Gnupg-users mailing list Gnupg-users@gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-users