From 9cb5a97b2cd5e8dd25b5da1ee48e869074850753 Mon Sep 17 00:00:00 2001 From: Kazuki Suzuki Przyborowski Date: Fri, 22 Nov 2024 15:04:19 -0600 Subject: [PATCH] Update --- upcean/encode/code11.py | 14 +---------- upcean/encode/code93.py | 30 +++++++++++++----------- upcean/validate/validate.py | 46 +++++++++++++++++++++++++++++++++---- 3 files changed, 59 insertions(+), 31 deletions(-) diff --git a/upcean/encode/code11.py b/upcean/encode/code11.py index 77daeb24..5b8de0e1 100644 --- a/upcean/encode/code11.py +++ b/upcean/encode/code11.py @@ -267,19 +267,7 @@ def draw_code11_barcode(upc, resize=1, barheight=(48, 54), barwidth=(1, 1), barc bcsize7 = len(re.findall("([1-8])", "".join(upc_matches))) upc_size_add = ((bcsize6 * 6) + (bcsize7 * 7) + len(upc_matches) - 1) * barwidth[0] - if(pilsupport and imageoutlib == "pillow"): - upc_preimg = Image.new( - "RGB", (((34 * barwidth[0]) + upc_size_add) * int(resize), (barheightadd + (9 * barwidth[1])) * int(resize))) - upc_img = ImageDraw.Draw(upc_preimg) - elif((cairosupport and (imageoutlib == "cairo" or imageoutlib == "cairosvg"))): - upc_preimg = cairo.RecordingSurface( - cairo.CONTENT_COLOR, (0.0, 0.0, float(((34 * barwidth[0]) + upc_size_add) * int(resize)), float((barheightadd + (9 * barwidth[1])) * int(resize)))) - upc_img = cairo.Context(upc_preimg) - upc_img.set_antialias(cairo.ANTIALIAS_NONE) - elif(svgwritesupport and imageoutlib=="svgwrite"): - upc_preimg = StringIO() - upc_img = svgwrite.Drawing(upc_preimg, profile='full', size=(((34 * barwidth[0]) + upc_size_add) * int(resize), (barheightadd + (9 * barwidth[1])) * int(resize))) - upc_preimg.close() + upc_img, upc_preimg = upcean.predraw.new_image_surface(((34 * barwidth[0]) + upc_size_add) * int(resize), (barheightadd + (9 * barwidth[1])) * int(resize), barcolor[2], imageoutlib) imgout = encode_code11_barcode([upc_img, upc_preimg], upc, resize, (0, 0), barheight, barwidth, barcolor, hideinfo, imageoutlib) return [upc_img, upc_preimg, imageoutlib] diff --git a/upcean/encode/code93.py b/upcean/encode/code93.py index 8bc2cc00..a9300f30 100644 --- a/upcean/encode/code93.py +++ b/upcean/encode/code93.py @@ -388,7 +388,8 @@ def get_code93extended_barcode_size(upc, resize=1, shiftxy=(0, 0), barheight=(48 if(not re.findall("^([0-9]*[\\.]?[0-9])", str(resize)) or int(resize) < 1): resize = 1 upc = upc.upper() - upc_matches = list(upc) + pattern = '\\(\\$\\)|\\(%\\)|\\(/\\)|\\(\\+\\)|[0-9A-Z\\-\\. \\$\\/\\+%]' + upc_matches = re.findall(pattern, upc) if(len(upc_matches) <= 0): return False upc_size_add = (len(upc_matches) * 9) * barwidth[0] @@ -437,7 +438,8 @@ def encode_code93extended_barcode(inimage, upc, resize=1, shiftxy=(0, 0), barhei vertical_text_fix = 0 vertical_text_fix += (shiftxy[1] * (int(resize) * barwidth[1])) upc = upc.upper() - upc_matches = list(upc) + pattern = '\\(\\$\\)|\\(%\\)|\\(/\\)|\\(\\+\\)|[0-9A-Z\\-\\. \\$\\/\\+%]' + upc_matches = re.findall(pattern, upc) if(len(upc_matches) <= 0): return False Code93Array = {0: "0", 1: "1", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "A", 11: "B", 12: "C", 13: "D", 14: "E", 15: "F", 16: "G", 17: "H", 18: "I", 19: "J", 20: "K", 21: "L", 22: "M", 23: "N", @@ -615,8 +617,8 @@ def encode_code93extended_barcode(inimage, upc, resize=1, shiftxy=(0, 0), barhei LineStart += barwidth[0] * int(resize) BarNum += 1 upc_array['barsize'].append(barsizeloop) - code93extended = {'%U': " ", '$A': " ", '$B': " ", '$C': " ", '$D': " ", '$E': " ", '$F': " ", '$G': " ", '$H': " ", '$I': " ", '$J': " ", '$K': " ", '$L': " ", '$M': " ", '$N': " ", '$O': " ", '$P': " ", '$Q': " ", '$R': " ", '$S': " ", '$T': " ", '$U': " ", '$V': " ", '$W': " ", '$X': " ", '$Y': " ", '$Z': " ", '%A': " ", '%B': " ", '%C': " ", '%D': " ", '%E': " ", ' ': " ", '/A': "!", '/B': "\"", '/C': "#", '$': "$", '%': "%", '/F': "&", '/G': "'", '/H': "(", '/I': "", '/J': "*", '+': "+", '/L': ",", '-': "-", '.': ".", '/': "/", '0': "0", '1': "1", '2': "2", '3': "3", '4': "4", '5': "5", '6': "6", '7': "7", '8': "8", '9': "9", '/Z': ":", '%F': ";", '%G': "<", '%H': "=", '%I': ">", '%J': "?", - '%V': "@", 'A': "A", 'B': "B", 'C': "C", 'D': "D", 'E': "E", 'F': "F", 'G': "G", 'H': "H", 'I': "I", 'J': "J", 'K': "K", 'L': "L", 'M': "M", 'N': "N", 'O': "O", 'P': "P", 'Q': "Q", 'R': "R", 'S': "S", 'T': "T", 'U': "U", 'V': "V", 'W': "W", 'X': "X", 'Y': "Y", 'Z': "Z", '%K': "[", '%L': "\\", '%M': "]", '%N': "^", '%O': "_", '%W': "`", '+A': "a", '+B': "b", '+C': "c", '+D': "d", '+E': "e", '+F': "f", '+G': "g", '+H': "h", '+I': "i", '+J': "j", '+K': "k", '+L': "l", '+M': "m", '+N': "n", '+O': "o", '+P': "p", '+Q': "q", '+R': "r", '+S': "s", '+T': "t", '+U': "u", '+V': "v", '+W': "w", '+X': "x", '+Y': "y", '+Z': "z", '%P': "{", '%Q': "|", '%R': "}", '%S': "~", '%T': " ", '%X': " ", '%Y': " ", '%Z': " "} + code93extended = {'(%)U': " ", '($)A': " ", '($)B': " ", '($)C': " ", '($)D': " ", '($)E': " ", '($)F': " ", '($)G': " ", '($)H': " ", '($)I': " ", '($)J': " ", '($)K': " ", '($)L': " ", '($)M': " ", '($)N': " ", '($)O': " ", '($)P': " ", '($)Q': " ", '($)R': " ", '($)S': " ", '($)T': " ", '($)U': " ", '($)V': " ", '($)W': " ", '($)X': " ", '($)Y': " ", '($)Z': " ", '(%)A': " ", '(%)B': " ", '(%)C': " ", '(%)D': " ", '(%)E': " ", ' ': " ", '(/)A': "!", '(/)B': "\"", '(/)C': "#", '($)': "$", '(/)F': "&", '(/)G': "'", '(/)H': "(", '(/)I': "", '(/)J': "*", '(/)L': ",", '-': "-", '.': ".", '0': "0", '1': "1", '2': "2", '3': "3", '4': "4", '5': "5", '6': "6", '7': "7", '8': "8", '9': "9", '(/)Z': ":", '(/)': "/", '(%)F': ";", '(%)G': "<", '(%)H': "=", '(%)I': ">", '(%)J': "?", + '(%)V': "@", '(%)K': "[", '(%)L': "\\", '(%)M': "]", '(%)N': "^", '(%)O': "_", '(%)W': "`", '(+)A': "a", '(+)B': "b", '(+)C': "c", '(+)D': "d", '(+)E': "e", '(+)F': "f", '(+)G': "g", '(+)H': "h", '(+)I': "i", '(+)J': "j", '(+)K': "k", '(+)L': "l", '(+)M': "m", '(+)N': "n", '(+)O': "o", '(+)P': "p", '(+)Q': "q", '(+)R': "r", '(+)S': "s", '(+)T': "t", '(+)U': "u", '(+)V': "v", '(+)W': "w", '(+)X': "x", '(+)Y': "y", '(+)Z': "z", '(+)': "+", '(%)P': "{", '(%)Q': "|", '(%)R': "}", '(%)S': "~", '(%)T': " ", '(%)X': " ", '(%)Y': " ", '(%)Z': " ", '(%)': "%"} NumTxtZero = 0 LineTxtStart = ((shiftxy[0] + 18) * int(resize)) LineTxtStartNorm = 18 @@ -626,21 +628,20 @@ def encode_code93extended_barcode(inimage, upc, resize=1, shiftxy=(0, 0), barhei LineTxtStart += (1 * int(resize)) while (NumTxtZero < len(upc_matches)): texthidden = False - NumTxtZeroNext = NumTxtZero + 1 - if(NumTxtZeroNext < len(upc_matches) and code93extended.get(upc_matches[NumTxtZero]+upc_matches[NumTxtZeroNext], False)): - LineTxtStart += 16 * int(resize) - LineTxtStartNorm += 16 + if(len(upc_matches[NumTxtZero])==3): + NumTxtZeroNext = NumTxtZero + 1 + nextchar = code93extended.get(upc_matches[NumTxtZero]+upc_matches[NumTxtZeroNext], " ") + LineTxtStart += 9 * int(resize) + LineTxtStartNorm += 9 drawColorText(upc_img, 10 * int(resize * barwidth[1]), LineTxtStart * barwidth[0], vertical_text_fix + ( - barheight[0] * int(resize)), code93extended.get(upc_matches[NumTxtZero]+upc_matches[NumTxtZeroNext], " "), barcolor[1], "ocrb", imageoutlib) + barheight[0] * int(resize)), nextchar, barcolor[1], "ocrb", imageoutlib) NumTxtZero += 1 else: drawColorText(upc_img, 10 * int(resize * barwidth[1]), LineTxtStart * barwidth[0], vertical_text_fix + ( barheight[0] * int(resize)), code93extended.get(upc_matches[NumTxtZero], upc_matches[NumTxtZero]), barcolor[1], "ocrb", imageoutlib) + #print(upc_matches[NumTxtZero], NumTxtZero) if hidetext: texthidden = True - if(not texthidden): - drawColorText(upc_img, 10 * int(resize * barwidth[1]), LineTxtStart * barwidth[0], vertical_text_fix + ( - barheight[0] * int(resize)), upc_matches[NumTxtZero], barcolor[1], "ocrb", imageoutlib) upc_array['text']['location'].append(LineTxtStartNorm) upc_array['text']['text'].append(upc_matches[NumTxtZero]) upc_array['text']['type'].append("txt") @@ -660,8 +661,9 @@ def draw_code93extended_barcode(upc, resize=1, barheight=(48, 54), barwidth=(1, barheightadd = barheight[1] if(imageoutlib not in imagelibsupport): imageoutlib = defaultdraw - upc_up = upc.upper() - upc_matches = list(upc_up) + upc = upc.upper() + pattern = '\\(\\$\\)|\\(%\\)|\\(/\\)|\\(\\+\\)|[0-9A-Z\\-\\. \\$\\/\\+%]' + upc_matches = re.findall(pattern, upc) if(len(upc_matches) <= 0): return False Code93Array = {0: "0", 1: "1", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "A", 11: "B", 12: "C", 13: "D", 14: "E", 15: "F", 16: "G", 17: "H", 18: "I", 19: "J", 20: "K", 21: "L", 22: "M", 23: "N", diff --git a/upcean/validate/validate.py b/upcean/validate/validate.py index 1a8ee13c..78d1c3fc 100644 --- a/upcean/validate/validate.py +++ b/upcean/validate/validate.py @@ -1288,7 +1288,8 @@ def get_code39_checksum(upc, getmod="43"): CODE93_VALUES.update({"-": 36, ".": 37, " ": 38, "$": 39, "/": 40, "+": 41, "%": 42, "($)": 43, "(%)": 44, "(/)": 45, "(+)": 46}) CODE93_ARRAY = {v: k for k, v in CODE93_VALUES.items()} -def get_code93_alt_checksum(upc): +def get_code93_checksum(upc): + import re # Validate input if len(upc) < 1 or not re.match("^[0-9A-Z\\-\\.\\$\\/\\+% ]+$", upc, re.IGNORECASE): return False @@ -1299,14 +1300,51 @@ def calculate_weighted_sum(upc_reversed, max_weight): # Calculate first checksum with max weight of 20 upc_reversed = upc[::-1].upper() - checksum1 = CODE93_ARRAY[calculate_weighted_sum(upc_reversed, 20) % 47] + checksum1_value = calculate_weighted_sum(upc_reversed, 20) % 47 + checksum1 = CODE93_ARRAY[checksum1_value] + + # Append the first checksum to the reversed input for the second calculation + upc_with_checksum1 = checksum1 + upc_reversed # Calculate second checksum with max weight of 15 - checksum2 = CODE93_ARRAY[calculate_weighted_sum(upc_reversed, 15) % 47] + checksum2_value = calculate_weighted_sum(upc_with_checksum1, 15) % 47 + checksum2 = CODE93_ARRAY[checksum2_value] # Return concatenated checksums return checksum1 + checksum2 +def get_code93extended_checksum(upc): + # Validate input + pattern = "^[0-9A-Z\\-\\.\\$\\/\\+\\%]+|(\\(\\$\\)|\\(\\%\\)|\\(\\+\\)|\\(\\/\\))+$" + if len(upc) < 1 or not re.match(pattern, upc, re.IGNORECASE): + return False + + # Normalize the input to uppercase + upc = upc.upper() + + # Parse sequences like ($), (%) into single characters for computation + extended_map = {"($)": "$", "(%)": "%", "(+)": "+", "(/)": "/"} + for key, value in extended_map.items(): + upc = upc.replace(key, value) + + # Helper function to calculate weighted sum with specified max weight + def calculate_weighted_sum(upc_reversed, max_weight): + return sum(((i % max_weight) + 1) * CODE93_VALUES[char] for i, char in enumerate(upc_reversed)) + + # Calculate first checksum with max weight of 20 + upc_reversed = upc[::-1] + checksum1_value = calculate_weighted_sum(upc_reversed, 20) % 47 + checksum1 = CODE93_ARRAY[checksum1_value] + + # Append the first checksum to the reversed input for the second calculation + upc_with_checksum1 = checksum1 + upc_reversed + + # Calculate second checksum with max weight of 15 + checksum2_value = calculate_weighted_sum(upc_with_checksum1, 15) % 47 + checksum2 = CODE93_ARRAY[checksum2_value] + + # Return concatenated checksums + return checksum1 + checksum2 ''' // Code 93 @@ -1315,7 +1353,7 @@ def calculate_weighted_sum(upc_reversed, max_weight): ''' -def get_code93_checksum(upc): +def get_code93_alt_checksum(upc): # Validate input if len(upc) < 1 or not re.match(r"^[0-9A-Z\\-\\.\\$\\/\\+% ]+$", upc, re.IGNORECASE): return False