Last active 1589045305

Encoding and decoding files with txt records

Alyssa Smith revised this gist 1589081304. Go to revision

1 file changed, 6 insertions, 2 deletions

txtrecord_encode.py

@@ -11,8 +11,12 @@ def main():
11 11 parser.add_argument("domain", help="Target domain")
12 12 parser.add_argument("--format", help="DNS record format, where {0} is the target domain (without trailing dot), and {1} is the record text (defaults to bind/named \"{0}. IN TXT '{1}'\")", default="{0}. IN TXT '{1}'")
13 13 args = parser.parse_args()
14 - with open(sys.stdin if args.input == "-" else args.input,"rb") as f:
15 - enc = base64.b64encode(f.read()).decode("utf-8")
14 + if args.input == "-":
15 + inp = sys.stdin.buffer.read()
16 + else:
17 + with open(args.input,"rb") as f:
18 + inp = f.read()
19 + enc = base64.b64encode(inp).decode("utf-8")
16 20 tot = len(enc)
17 21 tmp = 0
18 22 for n,block in enumerate(wrap(enc,65000)):

Alyssa Smith revised this gist 1589080956. Go to revision

1 file changed, 7 insertions, 3 deletions

txtrecord_decode.py

@@ -32,9 +32,13 @@ def main():
32 32 out += next_out
33 33 if not name:
34 34 break
35 -
36 - with open(sys.stdout if args.output == "-" else args.output, "wb") as f:
37 - f.write(base64.b64decode(out))
35 +
36 + if args.output == "-":
37 + sys.stdout.buffer.write(base64.b64decode(out))
38 + sys.stdout.flush()
39 + else:
40 + with open(args.output, "wb") as f:
41 + f.write(base64.b64decode(out))
38 42 return 0
39 43
40 44 if __name__ == "__main__":

Suv Smith revised this gist 1585412205. Go to revision

2 files changed, 23 insertions, 13 deletions

txtrecord_decode.py

@@ -1,8 +1,9 @@
1 1 #!/usr/bin/env python3
2 - # txtrecord_decode.py output.png logo.example.com
2 + # txtrecord_decode.py [-h] output.png logo.example.com
3 3 import dns.resolver # pip3 install dnspython
4 4 import base64
5 5 import sys
6 + from argparse import ArgumentParser
6 7 def parse_records(name):
7 8 _next = ""
8 9 print("{}".format(name), file=sys.stderr)
@@ -19,13 +20,22 @@ def parse_records(name):
19 20 pass
20 21 return out, _next
21 22
22 - out = b""
23 - name = sys.argv[2]
24 - while True:
25 - next_out, name = parse_records(name)
26 - out += next_out
27 - if not name:
28 - break
23 + def main():
24 + parser = ArgumentParser()
25 + parser.add_argument("output", help="Output filename (or - for stdout)")
26 + parser.add_argument("domain", help="Target domain")
27 + args = parser.parse_args()
28 + name = args.domain
29 + out = b""
30 + while True:
31 + next_out, name = parse_records(name)
32 + out += next_out
33 + if not name:
34 + break
35 +
36 + with open(sys.stdout if args.output == "-" else args.output, "wb") as f:
37 + f.write(base64.b64decode(out))
38 + return 0
29 39
30 - with open(sys.argv[1],"wb") as f:
31 - f.write(base64.b64decode(out))
40 + if __name__ == "__main__":
41 + sys.exit(main())

txtrecord_encode.py

@@ -1,5 +1,5 @@
1 1 #!/usr/bin/env python3
2 - # txtrecord_encode.py input.png logo.example.com [--format '{0} IN TXT "{1}"']
2 + # txtrecord_encode.py [-h] [--format '{0} IN TXT "{1}"'] input.png logo.example.com
3 3 import base64
4 4 import sys
5 5 from argparse import ArgumentParser
@@ -7,11 +7,11 @@ from textwrap import wrap
7 7
8 8 def main():
9 9 parser = ArgumentParser()
10 - parser.add_argument("input", help="Input filename")
10 + parser.add_argument("input", help="Input filename (or - for stdin)")
11 11 parser.add_argument("domain", help="Target domain")
12 12 parser.add_argument("--format", help="DNS record format, where {0} is the target domain (without trailing dot), and {1} is the record text (defaults to bind/named \"{0}. IN TXT '{1}'\")", default="{0}. IN TXT '{1}'")
13 13 args = parser.parse_args()
14 - with open(args.input,"rb") as f:
14 + with open(sys.stdin if args.input == "-" else args.input,"rb") as f:
15 15 enc = base64.b64encode(f.read()).decode("utf-8")
16 16 tot = len(enc)
17 17 tmp = 0

Suv Smith revised this gist 1585411428. Go to revision

1 file changed, 21 insertions, 13 deletions

txtrecord_encode.py

@@ -1,18 +1,26 @@
1 1 #!/usr/bin/env python3
2 - # txtrecord_encode.py input.png logo.example.com
2 + # txtrecord_encode.py input.png logo.example.com [--format '{0} IN TXT "{1}"']
3 3 import base64
4 4 import sys
5 + from argparse import ArgumentParser
5 6 from textwrap import wrap
6 - with open(sys.argv[1],"rb") as f:
7 - enc = base64.b64encode(f.read()).decode("utf-8")
8 7
9 - # '%04d' and '247' may need to be updated for large files to ensure the line count doesn't push the length
10 - # longer than 255 bytes
11 - tot = len(enc)
12 - tmp = 0
13 - for n,block in enumerate(wrap(enc,65000)):
14 - tmp += len(block)
15 - print("\n".join("{0}. IN TXT '{1}{2}'".format((str(n) if n else "") + sys.argv[2], "{%03d}" % _n, s) for _n, s in enumerate(wrap(block,249))))
16 - if tmp != tot:
17 - print("{0}. IN TXT '{1}{2}.".format((str(n) if n else "") + sys.argv[2], "{nxt}", str(n+1) + sys.argv[2]))
18 - #print("\n".join("%s. IN TXT '{%03d}%s'" % (sys.argv[2], n,s) for n,s in enumerate(wrap(enc,249))))
8 + def main():
9 + parser = ArgumentParser()
10 + parser.add_argument("input", help="Input filename")
11 + parser.add_argument("domain", help="Target domain")
12 + parser.add_argument("--format", help="DNS record format, where {0} is the target domain (without trailing dot), and {1} is the record text (defaults to bind/named \"{0}. IN TXT '{1}'\")", default="{0}. IN TXT '{1}'")
13 + args = parser.parse_args()
14 + with open(args.input,"rb") as f:
15 + enc = base64.b64encode(f.read()).decode("utf-8")
16 + tot = len(enc)
17 + tmp = 0
18 + for n,block in enumerate(wrap(enc,65000)):
19 + tmp += len(block)
20 + print("\n".join(args.format.format((str(n) if n else "") + sys.argv[2], "{}{}".format("{%03d}" % _n, s)) for _n, s in enumerate(wrap(block,249))))
21 + if tmp != tot:
22 + print(args.format.format((str(n) if n else "") + sys.argv[2], "{}{}".format("{nxt}", str(n+1) + sys.argv[2] + ".")))
23 + return 0
24 +
25 + if __name__ == "__main__":
26 + sys.exit(main())

Suv Smith revised this gist 1585409860. Go to revision

1 file changed, 4 insertions, 11 deletions

untitled.ipynb

Diff is too large to be shown

Suv Smith revised this gist 1585409762. Go to revision

1 file changed, 80 insertions, 20 deletions

untitled.ipynb

Diff is too large to be shown

blha303 revised this gist 1573815471. Go to revision

2 files changed, 32 insertions, 9 deletions

txtrecord_decode.py

@@ -3,13 +3,29 @@
3 3 import dns.resolver # pip3 install dnspython
4 4 import base64
5 5 import sys
6 - q = dns.resolver.query(sys.argv[2],"TXT").response.answer[0]
6 + def parse_records(name):
7 + _next = ""
8 + print("{}".format(name), file=sys.stderr)
9 + q = dns.resolver.query(name,"TXT").response.answer[0]
10 + out = b""
11 + for line in sorted(_.strings[0] for _ in q):
12 + if chr(line[0]) == "{":
13 + if chr(line[1]) == "n":
14 + _next = line.split(b"}",1)[1].decode("utf-8")
15 + continue
16 + try:
17 + out += line.split(b"}",1)[1]
18 + except IndexError:
19 + pass
20 + return out, _next
21 +
7 22 out = b""
8 - for line in sorted(_.strings[0] for _ in q):
9 - if chr(line[0]) == "{":
10 - try:
11 - out += line.split(b"}",1)[1]
12 - except IndexError:
13 - pass
23 + name = sys.argv[2]
24 + while True:
25 + next_out, name = parse_records(name)
26 + out += next_out
27 + if not name:
28 + break
29 +
14 30 with open(sys.argv[1],"wb") as f:
15 - f.write(base64.b64decode(out))
31 + f.write(base64.b64decode(out))

txtrecord_encode.py

@@ -8,4 +8,11 @@ with open(sys.argv[1],"rb") as f:
8 8
9 9 # '%04d' and '247' may need to be updated for large files to ensure the line count doesn't push the length
10 10 # longer than 255 bytes
11 - print("\n".join("%s. IN TXT '{%04d}%s'" % (sys.argv[2], n,s) for n,s in enumerate(wrap(enc,247))))
11 + tot = len(enc)
12 + tmp = 0
13 + for n,block in enumerate(wrap(enc,65000)):
14 + tmp += len(block)
15 + print("\n".join("{0}. IN TXT '{1}{2}'".format((str(n) if n else "") + sys.argv[2], "{%03d}" % _n, s) for _n, s in enumerate(wrap(block,249))))
16 + if tmp != tot:
17 + print("{0}. IN TXT '{1}{2}.".format((str(n) if n else "") + sys.argv[2], "{nxt}", str(n+1) + sys.argv[2]))
18 + #print("\n".join("%s. IN TXT '{%03d}%s'" % (sys.argv[2], n,s) for n,s in enumerate(wrap(enc,249))))

S Smith revised this gist 1568690992. Go to revision

1 file changed, 88 insertions

untitled.ipynb(file created)

@@ -0,0 +1,88 @@
1 + {
2 + "cells": [
3 + {
4 + "cell_type": "markdown",
5 + "metadata": {},
6 + "source": [
7 + "This is a test of Jupyter generating a cool blog post about a neat python project or something."
8 + ]
9 + },
10 + {
11 + "cell_type": "code",
12 + "execution_count": 10,
13 + "metadata": {},
14 + "outputs": [
15 + {
16 + "name": "stdout",
17 + "output_type": "stream",
18 + "text": [
19 + "b'test'\n",
20 + "b'{00}iVBORw0KGgoAAAAN...sQo8aFRo0+M8YCYKGjiE'\n",
21 + "b'{01}Q1CiALGgCAgINfud...ZGAkyJ9sDvO2DzNa4dZk'\n",
22 + "b'{02}E+BTF9RgIePCSjO3...UX6911GGr69VMh/3eWDV'\n",
23 + "b'{03}bE6tkPWUyTPRkqrY...bw8nGGgoCoYXopEPQ1Q7'\n"
24 + ]
25 + }
26 + ],
27 + "source": [
28 + "import dns.resolver\n",
29 + "import base64\n",
30 + "from IPython.display import HTML\n",
31 + "q = dns.resolver.query(\"logo.hosttel.com.au\",\"TXT\").response.answer[0]\n",
32 + "for line in sorted(_.strings[0] for _ in q)[:5]:\n",
33 + " print((line[:20] + b\"...\" + line[-20:]) if len(line) > 20 else line)"
34 + ]
35 + },
36 + {
37 + "cell_type": "code",
38 + "execution_count": 3,
39 + "metadata": {},
40 + "outputs": [
41 + {
42 + "data": {
43 + "text/html": [
44 + "<img src='data:image/png;base64,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'/>"
45 + ],
46 + "text/plain": [
47 + "<IPython.core.display.HTML object>"
48 + ]
49 + },
50 + "execution_count": 3,
51 + "metadata": {},
52 + "output_type": "execute_result"
53 + }
54 + ],
55 + "source": [
56 + "out = b\"\"\n",
57 + "for line in sorted(_.strings[0] for _ in q):\n",
58 + " if chr(line[0]) == \"{\":\n",
59 + " try:\n",
60 + " out += line.split(b\"}\",1)[1]\n",
61 + " except IndexError:\n",
62 + " pass\n",
63 + "HTML(\"<img src='data:image/png;base64,{0}'/>\".format(out.decode('utf-8')))"
64 + ]
65 + }
66 + ],
67 + "metadata": {
68 + "kernelspec": {
69 + "display_name": "Python 3",
70 + "language": "python",
71 + "name": "python3"
72 + },
73 + "language_info": {
74 + "codemirror_mode": {
75 + "name": "ipython",
76 + "version": 3
77 + },
78 + "file_extension": ".py",
79 + "mimetype": "text/x-python",
80 + "name": "python",
81 + "nbconvert_exporter": "python",
82 + "pygments_lexer": "ipython3",
83 + "version": "3.7.3"
84 + }
85 + },
86 + "nbformat": 4,
87 + "nbformat_minor": 2
88 + }

S Smith revised this gist 1568690799. Go to revision

1 file changed, 38 deletions

README.md (file deleted)

@@ -1,38 +0,0 @@
1 - This is a test of Jupyter generating a cool blog post about a neat python project or something.
2 -
3 -
4 - ```python
5 - import dns.resolver
6 - import base64
7 - from IPython.display import HTML
8 - q = dns.resolver.query("logo.hosttel.com.au","TXT").response.answer[0]
9 - for line in sorted(_.strings[0] for _ in q)[:5]:
10 - print((line[:20] + b"..." + line[-20:]) if len(line) > 20 else line)
11 - ```
12 -
13 - b'test'
14 - b'{00}iVBORw0KGgoAAAAN...sQo8aFRo0+M8YCYKGjiE'
15 - b'{01}Q1CiALGgCAgINfud...ZGAkyJ9sDvO2DzNa4dZk'
16 - b'{02}E+BTF9RgIePCSjO3...UX6911GGr69VMh/3eWDV'
17 - b'{03}bE6tkPWUyTPRkqrY...bw8nGGgoCoYXopEPQ1Q7'
18 -
19 -
20 -
21 - ```python
22 - out = b""
23 - for line in sorted(_.strings[0] for _ in q):
24 - if chr(line[0]) == "{":
25 - try:
26 - out += line.split(b"}",1)[1]
27 - except IndexError:
28 - pass
29 - HTML("<img src='data:image/png;base64,{0}'/>".format(out.decode('utf-8')))
30 - ```
31 -
32 -
33 -
34 -
35 - <img src='data:image/png;base64,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'/>
36 -
37 -
38 -

S Smith revised this gist 1568690723. Go to revision

1 file changed, 38 insertions

README.md(file created)

@@ -0,0 +1,38 @@
1 + This is a test of Jupyter generating a cool blog post about a neat python project or something.
2 +
3 +
4 + ```python
5 + import dns.resolver
6 + import base64
7 + from IPython.display import HTML
8 + q = dns.resolver.query("logo.hosttel.com.au","TXT").response.answer[0]
9 + for line in sorted(_.strings[0] for _ in q)[:5]:
10 + print((line[:20] + b"..." + line[-20:]) if len(line) > 20 else line)
11 + ```
12 +
13 + b'test'
14 + b'{00}iVBORw0KGgoAAAAN...sQo8aFRo0+M8YCYKGjiE'
15 + b'{01}Q1CiALGgCAgINfud...ZGAkyJ9sDvO2DzNa4dZk'
16 + b'{02}E+BTF9RgIePCSjO3...UX6911GGr69VMh/3eWDV'
17 + b'{03}bE6tkPWUyTPRkqrY...bw8nGGgoCoYXopEPQ1Q7'
18 +
19 +
20 +
21 + ```python
22 + out = b""
23 + for line in sorted(_.strings[0] for _ in q):
24 + if chr(line[0]) == "{":
25 + try:
26 + out += line.split(b"}",1)[1]
27 + except IndexError:
28 + pass
29 + HTML("<img src='data:image/png;base64,{0}'/>".format(out.decode('utf-8')))
30 + ```
31 +
32 +
33 +
34 +
35 + <img src='data:image/png;base64,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'/>
36 +
37 +
38 +
Newer Older