Skip to content

Commit 4492f6c

Browse files
committed
Broader changes to improve testing efforts as well as better handling of multi-logs
1 parent f9fe834 commit 4492f6c

27 files changed

+2407
-113
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
build/
33
dist/
44
*.egg-info/
5+
.eggs/

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ jobs:
1010
dist: xenial
1111

1212
script:
13-
- ./eac_logchecker.py logs/01.log
14-
- ./eac_logchecker.py logs/02.log
13+
- python3 setup.py test
1514

1615
deploy:
1716
provider: pypi

eac_logchecker.py

Lines changed: 67 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -3,98 +3,46 @@
33
import argparse
44
import contextlib
55
import json
6+
from pathlib import Path
67
import re
8+
import pprp
79

810
CHECKSUM_MIN_VERSION = ('V1.0', 'beta', '1')
911

1012

11-
def BYTE4(n):
12-
return (n & 0xFF000000) >> 24
13-
14-
def BYTE3(n):
15-
return (n & 0x00FF0000) >> 16
16-
17-
18-
def BYTE2(n):
19-
return (n & 0x0000FF00) >> 8
20-
21-
22-
def BYTE1(n):
23-
return (n & 0x000000FF) >> 0
24-
13+
def eac_checksum(text):
14+
# Ignore newlines
15+
text = text.replace('\r', '').replace('\n', '')
2516

26-
def rotate_right(n):
27-
return ((n & 0x000000FF) << 24) | (n >> 8)
17+
# Fuzzing reveals BOMs are also ignored
18+
text = text.replace('\ufeff', '').replace('\ufffe', '')
2819

20+
# Setup Rijndael-256 with a 256-bit blocksize
21+
cipher = pprp.crypto_3.rijndael(
22+
# Probably SHA256('super secret password') but it doesn't actually matter
23+
key=bytes.fromhex('9378716cf13e4265ae55338e940b376184da389e50647726b35f6f341ee3efd9'),
24+
block_size=256 // 8
25+
)
2926

30-
UNKNOWNS = [0x6C717893, 0x65423EF1, 0x8E3355AE, 0x61370B94, 0x9E38DA84, 0x26776450, 0x346F5FB3, 0xD9EFE31E, 0x1E44A783, 0x7B069972, 0xF535CCDC, 0x9402C748, 0xBC4F1CD6, 0x9A387886, 0xAE572735, 0x77B8C42B, 0xEFB1CB9D, 0x94B752EF, 0x61829E33, 0xF580597B, 0x5A82D7F7, 0xC0BAAF71, 0x6EED8844, 0x19554C6F, 0x476537B0, 0xD3D2655F, 0xB250FB6C, 0x47D0A217, 0xFAF2ED07, 0x3A484276, 0x54A5CA32, 0x4DF0865D, 0x0B86BBFC, 0xD854DEA3, 0x6A0425CF, 0x2DD487D8, 0x22BAFA66, 0x18F2B810, 0x4C577222, 0x01A7F47F, 0xD9FAE753, 0x01AE39F0, 0x6BAA1C3F, 0x467E9BE7, 0x7849EEF2, 0x60BB56E2, 0x2CEC24C0, 0x2D4BD0BF, 0xD1225403, 0xD08C6DF3, 0xBB2671CC, 0xFD58EA2B, 0x2C236903, 0x4C983FE1, 0x60741B21, 0x4D3FCB9E, 0xDAC1215C, 0x0A4D4CAF, 0xB16B3D63, 0x4C33D748, 0x05E06751, 0x497858B0, 0x290C4391, 0x6433880F, 0xAC82E218, 0xA6CFAEB7, 0x17A493D4, 0x5B97449C, 0x3C687C8F, 0x7510243F, 0x5C1C67AE, 0x382FEFA1, 0x9E85F7DC, 0x384A596B, 0x2FEECABF, 0x74798E23, 0xAEDE65A9, 0xDBCE4196, 0x87D22638, 0xBFFDC999, 0x708DA337, 0x48C7FA5C, 0x672930E3, 0x1350BEC0, 0xD38DCB13, 0x08438A85, 0x8F91ACBD, 0x306C6524, 0x4689F316, 0x0E4E094A, 0x696739A9, 0x7A378769, 0x0917DCEA, 0x0154566F, 0x8EC5FAD2, 0xBEA99FF6, 0x04272015, 0x0A69295F, 0x630E10F6, 0x1939979F, 0xDD055431, 0xDC51025E, 0x5294F88C, 0xEC3D677A, 0xDEE9073B, 0xD4802E64, 0xB78E3E92, 0xAEB7A90D, 0x39AC87E6, 0xE5FD85B8, 0xB7697D34, 0x5B541A4E, 0xF1D027D4, 0x255009B0, 0x92DE3722, 0x3C699E2F, 0xD2558CF3, 0x37A8094B, 0x80C1747F, 0xDB956E31]
31-
S_BOX = [0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]
27+
# Encode the text as UTF-16-LE
28+
plaintext = text.encode('utf-16-le')
3229

33-
T1 = [0xC6A56363, 0xF8847C7C, 0xEE997777, 0xF68D7B7B, 0xFF0DF2F2, 0xD6BD6B6B, 0xDEB16F6F, 0x9154C5C5, 0x60503030, 0x02030101, 0xCEA96767, 0x567D2B2B, 0xE719FEFE, 0xB562D7D7, 0x4DE6ABAB, 0xEC9A7676, 0x8F45CACA, 0x1F9D8282, 0x8940C9C9, 0xFA877D7D, 0xEF15FAFA, 0xB2EB5959, 0x8EC94747, 0xFB0BF0F0, 0x41ECADAD, 0xB367D4D4, 0x5FFDA2A2, 0x45EAAFAF, 0x23BF9C9C, 0x53F7A4A4, 0xE4967272, 0x9B5BC0C0, 0x75C2B7B7, 0xE11CFDFD, 0x3DAE9393, 0x4C6A2626, 0x6C5A3636, 0x7E413F3F, 0xF502F7F7, 0x834FCCCC, 0x685C3434, 0x51F4A5A5, 0xD134E5E5, 0xF908F1F1, 0xE2937171, 0xAB73D8D8, 0x62533131, 0x2A3F1515, 0x080C0404, 0x9552C7C7, 0x46652323, 0x9D5EC3C3, 0x30281818, 0x37A19696, 0x0A0F0505, 0x2FB59A9A, 0x0E090707, 0x24361212, 0x1B9B8080, 0xDF3DE2E2, 0xCD26EBEB, 0x4E692727, 0x7FCDB2B2, 0xEA9F7575, 0x121B0909, 0x1D9E8383, 0x58742C2C, 0x342E1A1A, 0x362D1B1B, 0xDCB26E6E, 0xB4EE5A5A, 0x5BFBA0A0, 0xA4F65252, 0x764D3B3B, 0xB761D6D6, 0x7DCEB3B3, 0x527B2929, 0xDD3EE3E3, 0x5E712F2F, 0x13978484, 0xA6F55353, 0xB968D1D1, 0x0, 0xC12CEDED, 0x40602020, 0xE31FFCFC, 0x79C8B1B1, 0xB6ED5B5B, 0xD4BE6A6A, 0x8D46CBCB, 0x67D9BEBE, 0x724B3939, 0x94DE4A4A, 0x98D44C4C, 0xB0E85858, 0x854ACFCF, 0xBB6BD0D0, 0xC52AEFEF, 0x4FE5AAAA, 0xED16FBFB, 0x86C54343, 0x9AD74D4D, 0x66553333, 0x11948585, 0x8ACF4545, 0xE910F9F9, 0x04060202, 0xFE817F7F, 0xA0F05050, 0x78443C3C, 0x25BA9F9F, 0x4BE3A8A8, 0xA2F35151, 0x5DFEA3A3, 0x80C04040, 0x058A8F8F, 0x3FAD9292, 0x21BC9D9D, 0x70483838, 0xF104F5F5, 0x63DFBCBC, 0x77C1B6B6, 0xAF75DADA, 0x42632121, 0x20301010, 0xE51AFFFF, 0xFD0EF3F3, 0xBF6DD2D2, 0x814CCDCD, 0x18140C0C, 0x26351313, 0xC32FECEC, 0xBEE15F5F, 0x35A29797, 0x88CC4444, 0x2E391717, 0x9357C4C4, 0x55F2A7A7, 0xFC827E7E, 0x7A473D3D, 0xC8AC6464, 0xBAE75D5D, 0x322B1919, 0xE6957373, 0xC0A06060, 0x19988181, 0x9ED14F4F, 0xA37FDCDC, 0x44662222, 0x547E2A2A, 0x3BAB9090, 0x0B838888, 0x8CCA4646, 0xC729EEEE, 0x6BD3B8B8, 0x283C1414, 0xA779DEDE, 0xBCE25E5E, 0x161D0B0B, 0xAD76DBDB, 0xDB3BE0E0, 0x64563232, 0x744E3A3A, 0x141E0A0A, 0x92DB4949, 0x0C0A0606, 0x486C2424, 0xB8E45C5C, 0x9F5DC2C2, 0xBD6ED3D3, 0x43EFACAC, 0xC4A66262, 0x39A89191, 0x31A49595, 0xD337E4E4, 0xF28B7979, 0xD532E7E7, 0x8B43C8C8, 0x6E593737, 0xDAB76D6D, 0x018C8D8D, 0xB164D5D5, 0x9CD24E4E, 0x49E0A9A9, 0xD8B46C6C, 0xACFA5656, 0xF307F4F4, 0xCF25EAEA, 0xCAAF6565, 0xF48E7A7A, 0x47E9AEAE, 0x10180808, 0x6FD5BABA, 0xF0887878, 0x4A6F2525, 0x5C722E2E, 0x38241C1C, 0x57F1A6A6, 0x73C7B4B4, 0x9751C6C6, 0xCB23E8E8, 0xA17CDDDD, 0xE89C7474, 0x3E211F1F, 0x96DD4B4B, 0x61DCBDBD, 0x0D868B8B, 0x0F858A8A, 0xE0907070, 0x7C423E3E, 0x71C4B5B5, 0xCCAA6666, 0x90D84848, 0x06050303, 0xF701F6F6, 0x1C120E0E, 0xC2A36161, 0x6A5F3535, 0xAEF95757, 0x69D0B9B9, 0x17918686, 0x9958C1C1, 0x3A271D1D, 0x27B99E9E, 0xD938E1E1, 0xEB13F8F8, 0x2BB39898, 0x22331111, 0xD2BB6969, 0xA970D9D9, 0x07898E8E, 0x33A79494, 0x2DB69B9B, 0x3C221E1E, 0x15928787, 0xC920E9E9, 0x8749CECE, 0xAAFF5555, 0x50782828, 0xA57ADFDF, 0x038F8C8C, 0x59F8A1A1, 0x09808989, 0x1A170D0D, 0x65DABFBF, 0xD731E6E6, 0x84C64242, 0xD0B86868, 0x82C34141, 0x29B09999, 0x5A772D2D, 0x1E110F0F, 0x7BCBB0B0, 0xA8FC5454, 0x6DD6BBBB, 0x2C3A1616]
34-
T2 = list(map(rotate_right, T1))
35-
T3 = list(map(rotate_right, T2))
36-
T4 = list(map(rotate_right, T3))
30+
# The IV is all zeroes so we don't have to handle it
31+
signature = b'\x00' * 32
3732

33+
# Process it block-by-block
34+
for i in range(0, len(plaintext), 32):
35+
# Zero-pad the last block, if necessary
36+
plaintext_block = plaintext[i:i + 32].ljust(32, b'\x00')
3837

39-
def eac_checksum(text):
40-
# Ignore newlines
41-
text = text.replace('\r', '').replace('\n', '')
38+
# CBC mode (XOR the previous ciphertext block into the plaintext)
39+
cbc_plaintext = bytes(a ^ b for a, b in zip(signature, plaintext_block))
4240

43-
# Fuzzing reveals BOMs are ignored
44-
text = text.replace('\ufeff', '').replace('\ufffe', '')
41+
# New signature is the ciphertext.
42+
signature = cipher.encrypt(cbc_plaintext)
4543

46-
# Initialize the "AES" state
47-
aes_state = [0, 0, 0, 0, 0, 0, 0, 0]
48-
49-
# Read the text in chunks of 16
50-
for i in range(0, len(text), 16):
51-
# Pad the final chunk with zero bytes
52-
chunk = text[i:i + 16].ljust(16, '\x00')
53-
54-
# Mix pairs of characters into the AES state
55-
for i, offset in enumerate(range(0, 16, 2)):
56-
aes_state[i] ^= int.from_bytes(chunk[offset:offset + 2].encode('utf-16le'), 'little')
57-
58-
# Perform one "AES" round
59-
a1 = UNKNOWNS[0] ^ aes_state[0]
60-
a2 = UNKNOWNS[1] ^ aes_state[1]
61-
a3 = UNKNOWNS[2] ^ aes_state[2]
62-
a4 = UNKNOWNS[3] ^ aes_state[3]
63-
a5 = UNKNOWNS[4] ^ aes_state[4]
64-
a6 = UNKNOWNS[5] ^ aes_state[5]
65-
a7 = UNKNOWNS[6] ^ aes_state[6]
66-
a8 = UNKNOWNS[7] ^ aes_state[7]
67-
68-
for i in range(0, 13):
69-
b1 = UNKNOWNS[ 8 + 8 * i] ^ (T1[BYTE4(a5)] ^ T2[BYTE3(a4)] ^ T3[BYTE2(a2)] ^ T4[BYTE1(a1)])
70-
b2 = UNKNOWNS[ 9 + 8 * i] ^ (T1[BYTE4(a6)] ^ T2[BYTE3(a5)] ^ T3[BYTE2(a3)] ^ T4[BYTE1(a2)])
71-
b3 = UNKNOWNS[10 + 8 * i] ^ (T1[BYTE4(a7)] ^ T2[BYTE3(a6)] ^ T3[BYTE2(a4)] ^ T4[BYTE1(a3)])
72-
b4 = UNKNOWNS[11 + 8 * i] ^ (T1[BYTE4(a8)] ^ T2[BYTE3(a7)] ^ T3[BYTE2(a5)] ^ T4[BYTE1(a4)])
73-
b5 = UNKNOWNS[12 + 8 * i] ^ (T1[BYTE4(a1)] ^ T2[BYTE3(a8)] ^ T3[BYTE2(a6)] ^ T4[BYTE1(a5)])
74-
b6 = UNKNOWNS[13 + 8 * i] ^ (T1[BYTE4(a2)] ^ T2[BYTE3(a1)] ^ T3[BYTE2(a7)] ^ T4[BYTE1(a6)])
75-
b7 = UNKNOWNS[14 + 8 * i] ^ (T1[BYTE4(a3)] ^ T2[BYTE3(a2)] ^ T3[BYTE2(a8)] ^ T4[BYTE1(a7)])
76-
b8 = UNKNOWNS[15 + 8 * i] ^ (T1[BYTE4(a4)] ^ T2[BYTE3(a3)] ^ T3[BYTE2(a1)] ^ T4[BYTE1(a8)])
77-
78-
a1 = b1
79-
a2 = b2
80-
a3 = b3
81-
a4 = b4
82-
a5 = b5
83-
a6 = b6
84-
a7 = b7
85-
a8 = b8
86-
87-
aes_state[0] = UNKNOWNS[112] ^ ((S_BOX[BYTE4(a5)] << 24) | (S_BOX[BYTE3(a4)] << 16) | (S_BOX[BYTE2(a2)] << 8) | S_BOX[BYTE1(a1)])
88-
aes_state[1] = UNKNOWNS[113] ^ ((S_BOX[BYTE4(a6)] << 24) | (S_BOX[BYTE3(a5)] << 16) | (S_BOX[BYTE2(a3)] << 8) | S_BOX[BYTE1(a2)])
89-
aes_state[2] = UNKNOWNS[114] ^ ((S_BOX[BYTE4(a7)] << 24) | (S_BOX[BYTE3(a6)] << 16) | (S_BOX[BYTE2(a4)] << 8) | S_BOX[BYTE1(a3)])
90-
aes_state[3] = UNKNOWNS[115] ^ ((S_BOX[BYTE4(a8)] << 24) | (S_BOX[BYTE3(a7)] << 16) | (S_BOX[BYTE2(a5)] << 8) | S_BOX[BYTE1(a4)])
91-
aes_state[4] = UNKNOWNS[116] ^ ((S_BOX[BYTE4(a1)] << 24) | (S_BOX[BYTE3(a8)] << 16) | (S_BOX[BYTE2(a6)] << 8) | S_BOX[BYTE1(a5)])
92-
aes_state[5] = UNKNOWNS[117] ^ ((S_BOX[BYTE4(a2)] << 24) | (S_BOX[BYTE3(a1)] << 16) | (S_BOX[BYTE2(a7)] << 8) | S_BOX[BYTE1(a6)])
93-
aes_state[6] = UNKNOWNS[118] ^ ((S_BOX[BYTE4(a3)] << 24) | (S_BOX[BYTE3(a2)] << 16) | (S_BOX[BYTE2(a8)] << 8) | S_BOX[BYTE1(a7)])
94-
aes_state[7] = UNKNOWNS[119] ^ ((S_BOX[BYTE4(a4)] << 24) | (S_BOX[BYTE3(a3)] << 16) | (S_BOX[BYTE2(a1)] << 8) | S_BOX[BYTE1(a8)])
95-
96-
# Dump out the "AES" state as hex
97-
return b''.join(n.to_bytes(4, 'little') for n in aes_state).hex().upper()
44+
# Textual signature is just the hex representation
45+
return signature.hex().upper()
9846

9947

10048
def extract_info(text):
@@ -108,9 +56,9 @@ def extract_info(text):
10856
else:
10957
version = tuple(version.split()[3:6])
11058

111-
match = re.search('\r?\n\r?\n==== (.*) ([A-Z0-9]+) ====', text)
59+
match = re.search('\n\n==== (.*) ([A-Z0-9]+) ====', text)
11260
if match:
113-
text, signature_parts = re.split('\r?\n\r?\n==== {}'.format(match.group(1)), text)
61+
text, signature_parts = re.split('\n\n==== {}'.format(match.group(1)), text)
11462
signature = signature_parts.split()[0].strip()
11563
else:
11664
signature = None
@@ -130,6 +78,10 @@ def get_logs(data):
13078
if text.startswith('\ufeff'):
13179
text = text[1:]
13280

81+
# The checksum strips off the newlines anyway, so we can simplify them here
82+
# for our own regexes
83+
text = text.replace('\r\n', '\n')
84+
13385
# Null bytes screw it up
13486
if '\x00' in text:
13587
text = text[:text.index('\x00')]
@@ -138,23 +90,21 @@ def get_logs(data):
13890
if any(len(l) + 1 > 2**13 for l in text.split('\n')):
13991
raise RuntimeError('EAC cannot handle lines longer than 2^13 chars')
14092

141-
return [x.strip() for x in re.split('^' + ('-' * 60), text)]
93+
return [x.strip() for x in re.split(r'[^-]-{60}[^-]', text)]
14294

14395

144-
def main():
145-
parser = argparse.ArgumentParser(description='Verifies and resigns EAC logs')
146-
parser.add_argument('--json', action='store_true', help='Output as JSON')
147-
parser.add_argument('file', type=argparse.FileType(mode='rb'), help='input log file')
148-
149-
args = parser.parse_args()
96+
def check_checksum(arg_file, arg_json):
97+
if not isinstance(arg_file, Path):
98+
arg_file = Path(arg_file)
99+
100+
output = []
150101

151-
cnt = 1
152-
output = {}
153-
print('Log Integrity Checker (C) 2010 by Andre Wiethoff')
154-
print('')
102+
if not arg_file.exists():
103+
if not arg_json:
104+
print('Could not find logfile to examine.')
155105

156106
try:
157-
with contextlib.closing(args.file) as open_file:
107+
with arg_file.open('rb') as open_file:
158108
logs = get_logs(open_file.read())
159109

160110
for log in logs:
@@ -170,27 +120,37 @@ def main():
170120
message = 'Log entry is fine!'
171121
status = "OK"
172122

173-
output[cnt] = {
174-
"name": args.file.name,
175-
"message": message
176-
}
177-
178-
if not args.json:
179-
print('{:d}. {:s}'.format(cnt, message))
180-
cnt += 1
181-
123+
output.append({
124+
"message": message,
125+
"status": status
126+
})
182127
except (UnicodeDecodeError, RuntimeError):
183128
message = 'Log entry has no checksum!'
184-
json_output[cnt] = {
185-
"name": args.file.name,
129+
output.append({
186130
"message": message,
187131
"status": "NO"
188-
}
189-
if not args.json:
190-
print('{:d}. {:s}'.format(cnt, message))
132+
})
133+
134+
return output
135+
191136

137+
def main():
138+
parser = argparse.ArgumentParser(description='Verifies and resigns EAC logs')
139+
parser.add_argument('--json', action='store_true', help='Output as JSON')
140+
parser.add_argument('file', type=Path, help='input log file')
141+
142+
args = parser.parse_args()
143+
144+
output = {}
145+
if not args.json:
146+
print('Log Integrity Checker (C) 2010 by Andre Wiethoff')
147+
print('')
148+
output = check_checksum(args.file, args.json)
192149
if args.json:
193150
print(json.dumps(output))
151+
else:
152+
for i in range(len(output)):
153+
print('{:d}. {:s}'.format(i+1, output[i]['message']))
194154

195155
if __name__ == '__main__':
196156
main()

logs/03.log

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
Exact Audio Copy V1.3 from 2. September 2016
2+
3+
EAC extraction logfile from 11. December 2016, 0:14
4+
5+
Die Toten Hosen / Alles was war
6+
7+
Used drive : SONY DVD RW DW-Q31A Adapter: 1 ID: 0
8+
9+
Read mode : Secure
10+
Utilize accurate stream : Yes
11+
Defeat audio cache : Yes
12+
Make use of C2 pointers : No
13+
14+
Read offset correction : 6
15+
Overread into Lead-In and Lead-Out : No
16+
Fill up missing offset samples with silence : Yes
17+
Delete leading and trailing silent blocks : No
18+
Null samples used in CRC calculations : Yes
19+
Used interface : Native Win32 interface for Win NT & 2000
20+
Gap handling : Appended to previous track
21+
22+
Used output format : User Defined Encoder
23+
Selected bitrate : 768 kBit/s
24+
Quality : High
25+
Add ID3 tag : No
26+
Command line compressor : C:\Program Files (x86)\Exact Audio Copy\FLAC\FLAC.EXE
27+
Additional command line options : -8 -e -p -V -T "ARTIST=%artist%" -T "TITLE=%title%" -T "ALBUM=%albumtitle%" -T "DATE=%year%" -T "TRACKNUMBER=%tracknr%" -T "GENRE=%genre%" -T "PERFORMER=%albuminterpret%" -T "COMPOSER=%composer%" %haslyrics%--tag-from-file=LYRICS="%lyricsfile%"%haslyrics% -T "ALBUMARTIST=%albumartist%" -T "DISCNUMBER=%cdnumber%" -T "TOTALDISCS=%totalcds%" -T "TOTALTRACKS=%numtracks%" -T "COMMENT=%comment%" %source% -o %dest%
28+
29+
30+
TOC of the extracted CD
31+
32+
Track | Start | Length | Start sector | End sector
33+
---------------------------------------------------------
34+
1 | 0:00.00 | 3:11.47 | 0 | 14371
35+
2 | 3:11.47 | 2:57.64 | 14372 | 27710
36+
3 | 6:09.36 | 3:01.30 | 27711 | 41315
37+
38+
39+
Track 1
40+
41+
Filename C:\music\Die Toten Hosen - Alles was war (2009) - FLAC\01 Alles was war.wav
42+
43+
Pre-gap length 0:00:02.00
44+
45+
Peak level 98.9 %
46+
Extraction speed 2.0 X
47+
Track quality 100.0 %
48+
Test CRC 869448B8
49+
Copy CRC 869448B8
50+
Accurately ripped (confidence 4) [62978ACD] (AR v2)
51+
Copy OK
52+
53+
Track 2
54+
55+
Filename C:\music\Die Toten Hosen - Alles was war (2009) - FLAC\02 Kaufen geh’n.wav
56+
57+
Pre-gap length 0:00:02.00
58+
59+
Peak level 98.9 %
60+
Extraction speed 2.0 X
61+
Track quality 100.0 %
62+
Test CRC B7700EDB
63+
Copy CRC B7700EDB
64+
Accurately ripped (confidence 4) [B8EB9063] (AR v2)
65+
Copy OK
66+
67+
Track 3
68+
69+
Filename C:\music\Die Toten Hosen - Alles was war (2009) - FLAC\03 Sorgen um Thomas.wav
70+
71+
Pre-gap length 0:00:02.00
72+
73+
Peak level 98.9 %
74+
Extraction speed 2.0 X
75+
Track quality 100.0 %
76+
Test CRC 2070269D
77+
Copy CRC 2070269D
78+
Accurately ripped (confidence 4) [996CB300] (AR v2)
79+
Copy OK
80+
81+
82+
All tracks accurately ripped
83+
84+
No errors occurred
85+
86+
End of status report
87+
88+
---- CUETools DB Plugin V2.1.6
89+
90+
[CTDB TOCID: 2o3xcCc7CTLin3lLbN00C8GQLh8-] found
91+
Submit result: 2o3xcCc7CTLin3lLbN00C8GQLh8- has been confirmed
92+
Track | CTDB Status
93+
1 | (9/9) Accurately ripped
94+
2 | (9/9) Accurately ripped
95+
3 | (9/9) Accurately ripped
96+
97+
98+
==== Log checksum B87329097185BB99031B35F90749EC4B82B4D8CA2CD23FFBD9575BB3D6E94613 ====

logs/04.log

28.4 KB
Binary file not shown.

logs/05.log

18.8 KB
Binary file not shown.

0 commit comments

Comments
 (0)