Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Python 3 and speedup #26

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python2
#-*- coding:utf-8 -*-
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from distutils.core import setup

Expand Down
4 changes: 2 additions & 2 deletions xortool/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python2
#-*- coding:utf-8 -*-
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

__all__ = ["args", "colors", "libcolors", "routine"]
__version__ = "0.98"
41 changes: 32 additions & 9 deletions xortool/args.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,54 @@
#!/usr/bin/env python2
#-*- coding:utf-8 -*-
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from docopt import docopt

from xortool.routine import parse_char
from xortool.charset import get_charset


class ArgError(Exception):
pass


def parse_char(ch):
"""
'A' or '\x41' or '0x41' or '41'
'\x00' or '0x00' or '00'
"""
if ch is None:
return None
if len(ch) == 1:
return bytes([ord(ch)])
if ch[0:2] in ("0x", "\\x"):
ch = ch[2:]
if not ch:
raise ValueError("Empty char")
if len(ch) > 2:
raise ValueError("Char can be only a char letter or hex")
return bytes([int(ch, 16)])


def parse_int(i):
if i is None:
return None
return int(i)


def parse_parameters(doc, version):
p = docopt(doc, version=version)
p = {k.lstrip("-"): v for k, v in p.items()}
try:
return {
"input_is_hex": bool(p["hex"]),
"max_key_length": int(p["max-keylen"]),
"known_key_length": int(p["key-length"]) if p["key-length"] else None,
"most_frequent_char": parse_char(p["char"]) if p["char"] else None,
"brute_chars": bool(p["brute-chars"]),
"brute_printable": bool(p["brute-printable"]),
"text_charset": get_charset(p["text-charset"]),
"frequency_spread": 0, # to be removed
"filename": p["FILE"] if p["FILE"] else "-", # stdin by default
"filter_output": bool(p["filter-output"]),
"frequency_spread": 0, # to be removed
"input_is_hex": bool(p["hex"]),
"known_key_length": parse_int(p["key-length"]),
"max_key_length": parse_int(p["max-keylen"]),
"most_frequent_char": parse_char(p["char"]),
"text_charset": get_charset(p["text-charset"]),
}
except ValueError as err:
raise ArgError(str(err))
17 changes: 12 additions & 5 deletions xortool/charset.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#!/usr/bin/env python
#-*- coding:utf-8 -*-
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import string

import numpy as np


class CharsetError(Exception):
pass
Expand All @@ -23,7 +25,7 @@ class CharsetError(Exception):
}


def get_charset(charset):
def _get_charset_string(charset):
charset = charset or "printable"
if charset in PREDEFINED_CHARSETS.keys():
return PREDEFINED_CHARSETS[charset]
Expand All @@ -32,5 +34,10 @@ def get_charset(charset):
for c in set(charset):
_ += CHARSETS[c]
return _
except KeyError as err:
raise CharsetError("Bad character set")
except KeyError:
raise CharsetError("Bad character set: ", charset)


def get_charset(charset):
charset_string = _get_charset_string(charset)
return np.array(list(bytes(charset_string, 'utf8')), dtype=np.uint8)
18 changes: 16 additions & 2 deletions xortool/colors.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python2
#-*- coding:utf-8 -*-
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from xortool.libcolors import color

Expand All @@ -17,3 +17,17 @@
C_KEY = color("red", attrs="bold")
C_BOLD = color(attrs="bold")
C_COUNT = color("yellow", attrs="bold")

COLORS = {
'C_RESET': C_RESET,
'C_FATAL': C_FATAL,
'C_WARN': C_WARN,
'C_KEYLEN': C_KEYLEN,
'C_PROB': C_PROB,
'C_BEST_KEYLEN': C_BEST_KEYLEN,
'C_BEST_PROB': C_BEST_PROB,
'C_DIV': C_DIV,
'C_KEY': C_KEY,
'C_BOLD': C_BOLD,
'C_COUNT': C_COUNT,
}
17 changes: 7 additions & 10 deletions xortool/libcolors.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python2
#-*- coding:utf-8 -*-
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import os

Expand All @@ -18,7 +18,7 @@

def _main():
header = color("white", "black", "dark")
print();
print()

print(header + " " + "Colors and backgrounds: " + color())
for c in _keys_sorted_by_values(BASH_COLORS):
Expand All @@ -37,7 +37,6 @@ def _main():
c1 + "red text" + color() + " " +
c2 + "white text" + color()))
print()
return


def color(color=None, bgcolor=None, attrs=None):
Expand All @@ -53,16 +52,14 @@ def color(color=None, bgcolor=None, attrs=None):
ret += ";" + BASH_ATTRIBUTES[attr]

if color:
if color in BASH_COLORS:
ret += ";" + BASH_COLORS[color]
else:
if color not in BASH_COLORS:
raise ValueError("Unknown color: " + color)
ret += ";" + BASH_COLORS[color]

if bgcolor:
if bgcolor in BASH_BGCOLORS:
ret += ";" + BASH_BGCOLORS[bgcolor]
else:
if bgcolor not in BASH_BGCOLORS:
raise ValueError("Unknown background color: " + bgcolor)
ret += ";" + BASH_BGCOLORS[bgcolor]

return ret + "m"

Expand Down
61 changes: 5 additions & 56 deletions xortool/routine.py
Original file line number Diff line number Diff line change
@@ -1,98 +1,47 @@
#!/usr/bin/env python2
#-*- coding:utf-8 -*-
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import os
import sys
import string


class MkdirError(Exception):
pass


def load_file(filename):
if filename == "-":
return sys.stdin.read()
fd = open(filename, "rb")
contents = fd.read()
fd.close()
return contents


def save_file(filename, data):
fd = open(filename, "wb")
fd.write(data)
fd.close()
return


def mkdir(dirname):
if os.path.exists(dirname):
return
try:
os.mkdir(dirname)
except BaseException as err:
raise MkdirError(str(err))
return


def rmdir(dirname):
if dirname[-1] == os.sep:
dirname = dirname[:-1]
if os.path.islink(dirname):
return # do not clear link - we can get out of dir
files = os.listdir(dirname)
for f in files:
if f == '.' or f == '..':
for f in os.listdir(dirname):
if f in ('.', '..'):
continue
path = dirname + os.sep + f
if os.path.isdir(path):
rmdir(path)
else:
os.unlink(path)
os.rmdir(dirname)
return


def decode_from_hex(text):
only_hex_digits = "".join([c for c in text if c in string.hexdigits])
return only_hex_digits.decode("hex")


def parse_char(ch):
"""
'A' or '\x41' or '41'
"""
if len(ch) == 1:
return ord(ch)
if ch[0:2] == "\\x":
ch = ch[2:]
if not ch:
raise ValueError("Empty char")
return ord(chr(int(ch, 16)))


def dexor(text, key):
ret = list(text)
mod = len(key)
for index, char in enumerate(ret):
ret[index] = chr(ord(char) ^ ord(key[index % mod]))
ret[index] = chr(char ^ ord(key[index % mod]))
return "".join(ret)


def die(exitMessage, exitCode=1):
print(exitMessage)
sys.exit(exitCode)


def is_linux():
return sys.platform.startswith("linux")


def alphanum(s):
lst = list(s)
for index, char in enumerate(lst):
if char in (string.letters + string.digits):
continue
lst[index] = char.encode("hex")
return "".join(lst)
Loading