Skip to content

Commit ce9e49e

Browse files
committed
implement checksums on each line of the plaintext output
Based on an idea by Peter Lebbing
1 parent e9bd8f1 commit ce9e49e

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,21 @@ by all programs, I chose not to use it.
112112
Each barcode is labeled with a start marker `^<sequence number><space>`. After that the raw
113113
and otherwise unencoded data follows.
114114

115+
## Plaintext output
116+
117+
paperbackup prints the plaintext in addition to the QR codes. If decoding one or more barcodes
118+
should fail, you can use it as fallback.
119+
120+
To ease entering large amounts of "gibberish" like base64 data, each line is printed with
121+
a checksum. The checksum is the first 6 hexadecimal characters of MD5 sum of the line content.
122+
The MD5 is on the "pure" line content without the line break (e.g. \n or \r\n)
123+
124+
To verify a line checksum use
125+
`echo -n "line content" | md5sum | cut -c -6`
126+
127+
If a line is too long to be printed on paper, it is split. This is denoted by a "^" character
128+
at the begin of the next line on paper. The "^" is not included in the checksum.
129+
115130
## Changing the paper format
116131

117132
The program writes PDFs in A4 by default. You can uncomment the respective lines

example_output.pdf

383 Bytes
Binary file not shown.

paperbackup.py

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import os
3131
import re
3232
import sys
33+
import hashlib
3334
import subprocess
3435
import qrencode
3536
from tempfile import mkstemp
@@ -46,6 +47,8 @@
4647
text_x_offset = 0
4748
text_y_offset = 8.2
4849

50+
plaintext_maxlinechars = 73
51+
4952
# the paperformat to use, activate the one you want
5053
paperformat_obj = document.paperformat.A4
5154
paperformat_str = "A4"
@@ -140,18 +143,58 @@ def finish_page(pdf, canv, pageno):
140143
fd, temp_text_path = mkstemp('.ps', 'text_', '.')
141144
input_file_modification = datetime.fromtimestamp(os.path.getmtime(input_path)).strftime("%Y-%m-%d %H:%M:%S")
142145

146+
# split lines on plaintext_maxlinechars - ( checksum_size + separator size)
147+
splitat=plaintext_maxlinechars - 8
148+
splitlines=[]
149+
for line in ascdata.splitlines():
150+
while len(line) > splitat:
151+
splitlines.append(line[:splitat])
152+
# add a ^ at the beginning of the broken line to mark the linebreak
153+
line="^"+line[splitat:]
154+
splitlines.append(line)
155+
156+
# add checksums to each line
157+
chksumlines=[]
158+
for line in splitlines:
159+
# remove the linebreak marks for checksumming
160+
if len(line) > 1 and line[0] == "^":
161+
sumon=line[1:]
162+
else:
163+
sumon=line
164+
165+
# use the first 6 bytes of MD5 as checksum
166+
chksum = hashlib.md5(sumon.encode('utf-8')).hexdigest()[:6]
167+
168+
# add the checksum right-justified to the line
169+
line+=" "*(splitat-len(line))
170+
line+=" |"+chksum
171+
172+
chksumlines.append(line)
173+
174+
# add some documentation around the plaintest
175+
outlines=[]
176+
coldoc=" "*splitat
177+
coldoc+=" | MD5"
178+
outlines.append(coldoc)
179+
outlines.extend(chksumlines)
180+
outlines.append("")
181+
outlines.append("")
182+
outlines.append("")
183+
outlines.append("--")
184+
outlines.append("Created with paperbackup.py")
185+
outlines.append("See https://github.com/intra2net/paperbackup/ for instructions")
186+
143187
# use "enscript" to create postscript with the plaintext
144188
p = subprocess.Popen(
145189
["enscript", "-p"+temp_text_path, "-f", "Courier12",
146190
"-M" + paperformat_str, "--header",
147191
just_filename + "|" + input_file_modification + "|Page $%"],
148192
stdout=subprocess.PIPE, stdin=subprocess.PIPE)
149193

150-
# send the file and a tag line to enscript
151-
p.stdin.write(ascdata.encode('utf-8'))
152-
p.stdin.write("\n\n\n--\n".encode('utf-8'))
153-
p.stdin.write("Created with paperbackup.py\n".encode('utf-8'))
154-
p.stdin.write("See https://github.com/intra2net/paperbackup/ for instructions\n".encode('utf-8'))
194+
# send the text to enscript
195+
for line in outlines:
196+
p.stdin.write(line.encode('utf-8'))
197+
p.stdin.write(os.linesep.encode('utf-8'))
155198

156199
p.communicate()[0]
157200
p.stdin.close()

0 commit comments

Comments
 (0)