From ded78270e80a5fbf949610337a00d956c97987bb Mon Sep 17 00:00:00 2001 From: samruddhisk <153628687+samruddhisk@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:53:08 +0530 Subject: [PATCH 1/4] Update decode.py New changes for pulling. --- pyaadhaar/decode.py | 594 ++++++++++++++++++++------------------------ 1 file changed, 274 insertions(+), 320 deletions(-) diff --git a/pyaadhaar/decode.py b/pyaadhaar/decode.py index 316f8da..6add37a 100644 --- a/pyaadhaar/decode.py +++ b/pyaadhaar/decode.py @@ -1,321 +1,275 @@ -import zlib -from io import BytesIO -from PIL import Image, ImageFile -ImageFile.LOAD_TRUNCATED_IMAGES = True -import xml.etree.ElementTree as ET -from io import BytesIO -import base64 -import zipfile -from typing import Union -from . import utils - -class AadhaarSecureQr: - # This is the class for Aadhaar Secure Qr code.. In this version of code the data is in encrypted format - # The special thing of this type of QR is that we can extract the photo of user from the data - # This class now supports 2022 version of Aadhaar QR codes [version-2] - # For more information check here : https://103.57.226.101/images/resource/User_manulal_QR_Code_15032019.pdf - - def __init__(self, base10encodedstring:str) -> None: - self.base10encodedstring = base10encodedstring - self.details = ["version","email_mobile_status","referenceid", "name", "dob", "gender", "careof", "district", "landmark", - "house", "location", "pincode", "postoffice", "state", "street", "subdistrict", "vtc", "last_4_digits_mobile_no"] - self.delimeter = [-1] - self.data = {} - self._convert_base10encoded_to_decompressed_array() - self._check_aadhaar_version() - self._create_delimeter() - self._extract_info_from_decompressed_array() - - # Converts base10encoded string to a decompressed array - def _convert_base10encoded_to_decompressed_array(self) -> None: - bytes_array = self.base10encodedstring.to_bytes(5000, 'big').lstrip(b'\x00') - self.decompressed_array = zlib.decompress(bytes_array, 16+zlib.MAX_WBITS) - - # This function will check for the new 2022 version-2 Aadhaar QRs - # If not found it will remove the "version" key from self.details, Defaulting to normal Secure QRs - def _check_aadhaar_version(self) -> None: - if self.decompressed_array[:2].decode("ISO-8859-1") != 'V2': - self.details.pop(0) # Removing "Version" - self.details.pop() # Removing "Last_4_digits_of_mobile_no" - - # Creates the delimeter which is used to extract the information from the decompressed array - def _create_delimeter(self) -> None: - for i in range(len(self.decompressed_array)): - if self.decompressed_array[i] == 255: - self.delimeter.append(i) - - # Extracts the information from the decompressed array - def _extract_info_from_decompressed_array(self) -> None: - for i in range(len(self.details)): - self.data[self.details[i]] = self.decompressed_array[self.delimeter[i] + 1:self.delimeter[i+1]].decode("ISO-8859-1") - self.data['aadhaar_last_4_digit'] = self.data['referenceid'][:4] - self.data['aadhaar_last_digit'] = self.data['referenceid'][3] - # Default values to 'email' and 'mobile - self.data['email'] = False - self.data['mobile'] = False - # Updating the fields of 'email' and 'mobile' - if int(self.data['email_mobile_status']) in {3, 1}: - self.data['email'] = True - if int(self.data['email_mobile_status']) in {3, 2}: - self.data['mobile'] = True - - # Returns the extracted data in a dictionary format - def decodeddata(self) -> dict: - return self.data - - # Returns signature of the QR code - def signature(self) -> bytes: - return self.decompressed_array[len(self.decompressed_array) - 256 :] - - # Returns the signed data of the QR code - def signedData(self) -> bytes: - return self.decompressed_array[:len(self.decompressed_array)-256] - - # Check whether mobile no is registered or not - def isMobileNoRegistered(self) -> bool: - return self.data['mobile'] - - # Check whether email id is registered or not - def isEmailRegistered(self) -> bool: - return self.data['email'] - - # Return hash of the email id - def sha256hashOfEMail(self) -> str: - tmp = "" - if int(self.data['email_mobile_status']) == 3: - tmp = self.decompressed_array[len(self.decompressed_array)-256-32-32:len(self.decompressed_array)-256-32].hex() - elif int(self.data['email_mobile_status']) == 1: - tmp = self.decompressed_array[len(self.decompressed_array)-256-32:len(self.decompressed_array)-256].hex() - return tmp - - # Return hash of the mobile number - def sha256hashOfMobileNumber(self) -> str: - return ( - self.decompressed_array[ - len(self.decompressed_array) - - 256 - - 32 : len(self.decompressed_array) - - 256 - ].hex() - if int(self.data['email_mobile_status']) in {3, 2} - else "" - ) - - # Check availability of image in the QR CODE - def isImage(self, buffer = 10) -> bool: - if int(self.data['email_mobile_status']) == 3: - return ( - len( - self.decompressed_array[ - self.delimeter[len(self.details)] + 1 : - ] - ) - >= 256 + 32 + 32 + buffer - ) - elif int(self.data['email_mobile_status']) in {2, 1}: - return ( - len( - self.decompressed_array[ - self.delimeter[len(self.details)] + 1 : - ] - ) - >= 256 + 32 + buffer - ) - elif int(self.data['email_mobile_status']) == 0: - return ( - len( - self.decompressed_array[ - self.delimeter[len(self.details)] + 1 : - ] - ) - >= 256 + buffer - ) +# import zlib +# from io import BytesIO +# from PIL import Image, ImageFile +# ImageFile.LOAD_TRUNCATED_IMAGES = True +# import base64 +# import zipfile +# import xml.etree.ElementTree as ET +# from typing import Union +# from pyaadhaar import utils + +# class AadhaarSecureQr: +# def __init__(self, base10encodedstring: str) -> None: +# self.base10encodedstring = base10encodedstring +# self.details_v1 = ["version", "email_mobile_status", "referenceid", "name", "dob", "gender", "careof", "district", "landmark", +# "house", "location", "pincode", "postoffice", "state", "street", "subdistrict", "vtc", "last_4_digits_mobile_no"] +# self.details_v2 = ["email_mobile_status", "referenceid", "name", "dob", "gender", "careof", "district", "landmark", +# "house", "location", "pincode", "postoffice", "state", "street", "subdistrict", "vtc"] +# self.delimiter = [-1] +# self.data = {} +# self._convert_base10encoded_to_decompressed_array() +# self._detect_version_and_adjust_details() +# self._create_delimiter() +# self._extract_info_from_decompressed_array() + +# def _convert_base10encoded_to_decompressed_array(self) -> None: +# bytes_array = self.base10encodedstring.to_bytes(5000, 'big').lstrip(b'\x00') +# print(f"Bytes array (trimmed leading zeros): {bytes_array[:100]}") # Debugging: print the first 100 bytes +# try: +# self.decompressed_array = zlib.decompress(bytes_array, 16 + zlib.MAX_WBITS) +# except Exception as e: +# print(f"Decompression error: {e}") +# return +# print(f"Decompressed array: {self.decompressed_array[:100]}") # Debugging: print the first 100 bytes of decompressed array + +# def _detect_version_and_adjust_details(self) -> None: +# # Check for version in the first two bytes +# version = self.decompressed_array[:2].decode("ISO-8859-1") +# if version.startswith('V'): +# # Version is present, use the details list with version +# self.details = self.details_v1 +# else: +# # Version is not present, use the details list without version +# self.details = self.details_v2 + +# def _create_delimiter(self) -> None: +# for i in range(len(self.decompressed_array)): +# if self.decompressed_array[i] == 255: +# self.delimiter.append(i) +# print(f"Delimiters: {self.delimiter}") + +# def _extract_info_from_decompressed_array(self) -> None: +# for i in range(len(self.details)): +# if i + 1 < len(self.delimiter): +# start_idx = self.delimiter[i] + 1 +# end_idx = self.delimiter[i + 1] +# self.data[self.details[i]] = self.decompressed_array[start_idx:end_idx].decode("ISO-8859-1") + +# print(f"Extracted data before verification: {self.data}") + +# referenceid = self.data.get('referenceid', '') +# if len(referenceid) >= 4: +# self.data['aadhaar_last_4_digit'] = referenceid[:4] +# self.data['aadhaar_last_digit'] = referenceid[3] +# else: +# print(f"Reference ID is too short: {referenceid}") +# print(f"Extracted data: {self.data}") + +# self.data['email'] = False +# self.data['mobile'] = False +# email_mobile_status = self.data.get('email_mobile_status', '') +# if email_mobile_status.isdigit(): +# email_mobile_status = int(email_mobile_status) +# if email_mobile_status in {3, 1}: +# self.data['email'] = True +# if email_mobile_status in {3, 2}: +# self.data['mobile'] = True + +# def decodeddata(self) -> dict: +# return self.data + +# def signature(self) -> bytes: +# return self.decompressed_array[len(self.decompressed_array) - 256:] + +# def signedData(self) -> bytes: +# return self.decompressed_array[:len(self.decompressed_array) - 256] + +# def isMobileNoRegistered(self) -> bool: +# return self.data['mobile'] + +# def isEmailRegistered(self) -> bool: +# return self.data['email'] + +# def sha256hashOfEMail(self) -> str: +# tmp = "" +# email_mobile_status = self.data.get('email_mobile_status', '') +# if email_mobile_status.isdigit() and int(email_mobile_status) == 3: +# tmp = self.decompressed_array[len(self.decompressed_array) - 256 - 32 - 32:len(self.decompressed_array) - 256 - 32].hex() +# elif email_mobile_status.isdigit() and int(email_mobile_status) == 1: +# tmp = self.decompressed_array[len(self.decompressed_array) - 256 - 32:len(self.decompressed_array) - 256].hex() +# return tmp + +# def sha256hashOfMobileNumber(self) -> str: +# email_mobile_status = self.data.get('email_mobile_status', '') +# if email_mobile_status.isdigit() and int(email_mobile_status) in {3, 2}: +# return self.decompressed_array[len(self.decompressed_array) - 256 - 32: len(self.decompressed_array) - 256].hex() +# return "" + +# def isImage(self, buffer=10) -> bool: +# email_mobile_status = self.data.get('email_mobile_status', '') +# if email_mobile_status.isdigit(): +# if int(email_mobile_status) == 3: +# return len(self.decompressed_array[self.delimiter[len(self.details)] + 1:]) >= 256 + 32 + 32 + buffer +# elif int(email_mobile_status) in {2, 1}: +# return len(self.decompressed_array[self.delimiter[len(self.details)] + 1:]) >= 256 + 32 + buffer +# elif int(email_mobile_status) == 0: +# return len(self.decompressed_array[self.delimiter[len(self.details)] + 1:]) >= 256 + buffer +# return False + +# def image(self) -> Union[Image.Image, None]: +# email_mobile_status = self.data.get('email_mobile_status', '') +# if email_mobile_status.isdigit() and int(email_mobile_status) in {0, 1, 2, 3}: +# return Image.open(BytesIO(self.decompressed_array[self.delimiter[len(self.details)] + 1:])) +# return None + +# def saveimage(self, filepath: str) -> None: +# image = self.image() +# if image: +# image.load() +# image.save(filepath) + +# def contains_image(self) -> bool: +# return self.isImage() - # Return image stream - def image(self) -> Union[Image.Image,None]: - if int(self.data['email_mobile_status']) == 3: - return Image.open( - BytesIO( - self.decompressed_array[ - self.delimeter[len(self.details)] + 1 : - ] - ) - ) - elif int(self.data['email_mobile_status']) in {2, 1}: - return Image.open( - BytesIO( - self.decompressed_array[ - self.delimeter[len(self.details)] + 1 : - ] - ) - ) - elif int(self.data['email_mobile_status']) == 0: - return Image.open( - BytesIO( - self.decompressed_array[ - self.delimeter[len(self.details)] + 1 : - ] - ) - ) - else: - return None - - # Save the image of the user - def saveimage(self, filepath:str) -> None: - image = self.image() - image.load() - image.save(filepath) - - # Verify the email id - def verifyEmail(self, emailid:str) -> bool: - if type(emailid) != str: - raise TypeError("Email id should be string") - generated_sha_mail = utils.SHAGenerator(emailid, self.data['aadhaar_last_digit']) - return generated_sha_mail == self.sha256hashOfEMail() - - # Verify the mobile no - def verifyMobileNumber(self, mobileno:str) -> bool: - if type(mobileno) != str: - raise TypeError("Mobile number should be string") - generated_sha_mobile = utils.SHAGenerator(mobileno, self.data['aadhaar_last_digit']) - return generated_sha_mobile == self.sha256hashOfMobileNumber() - - -class AadhaarOldQr: - # This is the class for Aadhaar Normal Qr code.. In this version of code the data is in XML v1.0 format - # For more information check here : https://103.57.226.101/images/resource/User_manulal_QR_Code_15032019.pdf - - def __init__(self, qrdata) -> None: - self.qrdata = qrdata - self.xmlparser = ET.XMLParser(encoding="utf-8") - self.parsedxml = ET.fromstring(qrdata, parser=self.xmlparser) - self.data = self.parsedxml.attrib - - def decodeddata(self) -> dict: - # Will return the decoded datas inn dictionary format - return self.data - - -class AadhaarOfflineXML: - - # This is the class for Aadhaar Offline XML - # The special thing of Offline XML is that we can extract the high quality photo of user from the data - # For more information check here : https://103.57.226.101/images/resource/User_manulal_QR_Code_15032019.pdf - - def __init__(self, file:str, passcode:str) -> None: - # Need to pass the zip file and passcode/sharecode to this function - self.passcode = passcode - self.data = {} - zf = zipfile.ZipFile(file, 'r') - zf.setpassword(str(self.passcode).encode('utf-8')) - filedata = zf.open(zf.namelist()[0]).read() - parsedxml = ET.fromstring( - filedata, parser=ET.XMLParser(encoding="utf-8")) - self.root = parsedxml - - self.hashofmobile = self.root[0][0].attrib['m'] - self.hashofemail = self.root[0][0].attrib['e'] - - if self.hashofmobile != "" and self.hashofemail != "": - self.data['email_mobile_status'] = "3" - elif self.hashofmobile == "" and self.hashofemail != "": - self.data['email_mobile_status'] = "2" - elif self.hashofmobile != "" and self.hashofemail == "": - self.data['email_mobile_status'] = "1" - elif self.hashofmobile == "" and self.hashofemail == "": - self.data['email_mobile_status'] = "0" - - self.data['referenceid'] = self.root.attrib['referenceId'] - self.data['name'] = self.root[0][0].attrib['name'] - self.data['dob'] = self.root[0][0].attrib['dob'] - self.data['gender'] = self.root[0][0].attrib['gender'] - self.data['careof'] = self.root[0][1].attrib['careof'] - self.data['district'] = self.root[0][1].attrib['dist'] - self.data['landmark'] = self.root[0][1].attrib['landmark'] - self.data['house'] = self.root[0][1].attrib['house'] - self.data['location'] = self.root[0][1].attrib['loc'] - self.data['pincode'] = self.root[0][1].attrib['pc'] - self.data['postoffice'] = self.root[0][1].attrib['po'] - self.data['state'] = self.root[0][1].attrib['state'] - self.data['street'] = self.root[0][1].attrib['street'] - self.data['subdistrict'] = self.root[0][1].attrib['subdist'] - self.data['vtc'] = self.root[0][1].attrib['vtc'] - self.data['aadhaar_last_4_digit'] = self.data['referenceid'][0:4] - self.data['aadhaar_last_digit'] = self.data['referenceid'][3] - - if self.data['email_mobile_status'] == "0": - self.data['email'] = False - self.data['mobile'] = False - elif self.data['email_mobile_status'] == "1": - self.data['email'] = True - self.data['mobile'] = False - elif self.data['email_mobile_status'] == "2": - self.data['email'] = False - self.data['mobile'] = True - elif self.data['email_mobile_status'] == "3": - self.data['email'] = True - self.data['mobile'] = True - - # Get decoded data in dictionary format - def decodeddata(self) -> dict: - return self.data - - # Fetch signature - def signature(self) -> str: - return self.root[1][1].text - - # Check if mobile number is registered - def isMobileNoRegistered(self) -> bool: - # Will return True if mobile number is registered - if int(self.data['email_mobile_status']) == 3 or int(self.data['email_mobile_status']) == 1: - return True - return False - - # Check if email id is registered - def isEmailRegistered(self) -> bool: - # Will return True if email id is registered - if int(self.data['email_mobile_status']) == 3 or int(self.data['email_mobile_status']) == 2: - return True - return False - - # Get the hash of email id - def sha256hashOfEMail(self) -> str: - # Will return the hash of the email id - return self.hashofemail - - # Get the hash of mobile number - def sha256hashOfMobileNumber(self) -> str: - # Will return the hash of mobile number - return self.hashofmobile - - # Get the image of user - def image(self) -> Image.Image: - # Will return the image stream to be used in another function - img = self.root[0][2].text - img = Image.open(BytesIO(base64.b64decode(img))) - return img - - # Save the image of user - def saveimage(self, filepath:str) -> None: - # Will save the image of user - image = self.image() - image.save(filepath) - - # Verify the email id - def verifyEmail(self, emailid:str) -> bool: - # Will return True if emailid match with the given email id - generated_sha_mail = utils.SHAGenerator( - str(emailid)+str(self.passcode), self.data['aadhaar_last_digit']) - if generated_sha_mail == self.sha256hashOfEMail(): - return True - else: - return False - - # Verify the mobile number - def verifyMobileNumber(self, mobileno:str) -> bool: - # Will return True if mobileno match with the given mobile no - generated_sha_mobile = utils.SHAGenerator(str(mobileno)+str(self.passcode), self.data['aadhaar_last_digit']) - if generated_sha_mobile == self.sha256hashOfMobileNumber(): - return True - else: - return False \ No newline at end of file + +# class AadhaarOldQr: +# # This is the class for Adhaar Normal Qr code.. In this version of code the data is in XML v1.0 format +# # For more information check here : https://103.57.226.101/images/resource/User_manulal_QR_Code_15032019.pdf + +# def __init__(self, qrdata): +# self.qrdata = qrdata +# self.xmlparser = ET.XMLParser(encoding="utf-8") +# self.parsedxml = ET.fromstring(qrdata, parser=self.xmlparser) +# self.data = self.parsedxml.attrib + +# def decodeddata(self): +# # Will return the decoded datas inn dictionary format +# return self.data + + +# class AadhaarOfflineXML: + +# # This is the class for Adhaar Offline XML +# # The special thing of Offline XML is that we can extract the high quality photo of user from the data +# # For more information check here : https://103.57.226.101/images/resource/User_manulal_QR_Code_15032019.pdf + +# def __init__(self, file, passcode): +# # Need to pass the zip file and passcode/sharecode to this function +# self.passcode = passcode +# self.data = {} +# zf = zipfile.ZipFile(file, 'r') +# zf.setpassword(str(self.passcode).encode('utf-8')) +# filedata = zf.open(zf.namelist()[0]).read() +# parsedxml = ET.fromstring( +# filedata, parser=ET.XMLParser(encoding="utf-8")) +# self.root = parsedxml + +# self.hashofmobile = self.root[0][0].attrib['m'] +# self.hashofemail = self.root[0][0].attrib['e'] + +# if self.hashofmobile != "" and self.hashofemail != "": +# self.data['email_mobile_status'] = "3" +# elif self.hashofmobile == "" and self.hashofemail != "": +# self.data['email_mobile_status'] = "2" +# elif self.hashofmobile != "" and self.hashofemail == "": +# self.data['email_mobile_status'] = "1" +# elif self.hashofmobile == "" and self.hashofemail == "": +# self.data['email_mobile_status'] = "0" + +# self.data['referenceid'] = self.root.attrib['referenceId'] +# self.data['name'] = self.root[0][0].attrib['name'] +# self.data['dob'] = self.root[0][0].attrib['dob'] +# self.data['gender'] = self.root[0][0].attrib['gender'] +# self.data['careof'] = self.root[0][1].attrib['careof'] +# self.data['district'] = self.root[0][1].attrib['dist'] +# self.data['landmark'] = self.root[0][1].attrib['landmark'] +# self.data['house'] = self.root[0][1].attrib['house'] +# self.data['location'] = self.root[0][1].attrib['loc'] +# self.data['pincode'] = self.root[0][1].attrib['pc'] +# self.data['postoffice'] = self.root[0][1].attrib['po'] +# self.data['state'] = self.root[0][1].attrib['state'] +# self.data['street'] = self.root[0][1].attrib['street'] +# self.data['subdistrict'] = self.root[0][1].attrib['subdist'] +# self.data['vtc'] = self.root[0][1].attrib['vtc'] +# self.data['adhaar_last_4_digit'] = self.data['referenceid'][0:4] +# self.data['adhaar_last_digit'] = self.data['referenceid'][3] + +# if self.data['email_mobile_status'] == "0": +# self.data['email'] = "no" +# self.data['mobile'] = "no" +# elif self.data['email_mobile_status'] == "1": +# self.data['email'] = "yes" +# self.data['mobile'] = "no" +# elif self.data['email_mobile_status'] == "2": +# self.data['email'] = "no" +# self.data['mobile'] = "yes" +# elif self.data['email_mobile_status'] == "3": +# self.data['email'] = "yes" +# self.data['mobile'] = "yes" + +# def decodeddata(self): +# # Will return data in dictionary format +# return self.data + +# def signature(self): +# # Will return the signature +# return self.root[1][1].text + +# def isMobileNoRegistered(self): +# # Will return True if mobile number is registered +# if int(self.data['email_mobile_status']) == 3 or int(self.data['email_mobile_status']) == 1: +# return True +# return False + +# def isEmailRegistered(self): +# # Will return True if email id is registered +# if int(self.data['email_mobile_status']) == 3 or int(self.data['email_mobile_status']) == 2: +# return True +# return False + +# def sha256hashOfEMail(self): +# # Will return the hash of the email id +# return self.hashofemail + +# def sha256hashOfMobileNumber(self): +# # Will return the hash of mobile number +# return self.hashofmobile + +# def image(self): +# # Will return the image stream to be used in another function +# img = self.root[0][2].text +# img = Image.open(BytesIO(base64.b64decode(img))) +# return img + +# def saveimage(self, filename): +# # Will save the image of user +# image = self.image() +# image.save(filename) + +# def contains_image(self) -> bool: +# try: +# img_data = self.root[0][2].text +# if img_data: +# Image.open(BytesIO(base64.b64decode(img_data))) +# return True +# except Exception as e: +# print(f"Error checking image: {e}") +# return False + +# def verifyEmail(self, emailid): +# # Will return True if emailid match with the given email id +# generated_sha_mail = utils.SHAGenerator( +# str(emailid)+str(self.passcode), self.data['adhaar_last_digit']) +# if generated_sha_mail == self.sha256hashOfEMail(): +# return True +# else: +# return False + +# def verifyMobileNumber(self, mobileno): +# # Will return True if mobileno match with the given mobile no +# generated_sha_mobile = utils.SHAGenerator( +# str(mobileno)+str(self.passcode), self.data['adhaar_last_digit']) +# if generated_sha_mobile == self.sha256hashOfMobileNumber(): +# return True +# else: +# return False From c329ad8a3a570b8a0ceb42c81c308dd51126f84e Mon Sep 17 00:00:00 2001 From: samruddhisk <153628687+samruddhisk@users.noreply.github.com> Date: Mon, 29 Jul 2024 09:56:28 +0530 Subject: [PATCH 2/4] Updated decode.py I have uncommented the code now. --- pyaadhaar/decode.py | 544 ++++++++++++++++++++++---------------------- 1 file changed, 272 insertions(+), 272 deletions(-) diff --git a/pyaadhaar/decode.py b/pyaadhaar/decode.py index 6add37a..86d4f74 100644 --- a/pyaadhaar/decode.py +++ b/pyaadhaar/decode.py @@ -1,275 +1,275 @@ -# import zlib -# from io import BytesIO -# from PIL import Image, ImageFile -# ImageFile.LOAD_TRUNCATED_IMAGES = True -# import base64 -# import zipfile -# import xml.etree.ElementTree as ET -# from typing import Union -# from pyaadhaar import utils - -# class AadhaarSecureQr: -# def __init__(self, base10encodedstring: str) -> None: -# self.base10encodedstring = base10encodedstring -# self.details_v1 = ["version", "email_mobile_status", "referenceid", "name", "dob", "gender", "careof", "district", "landmark", -# "house", "location", "pincode", "postoffice", "state", "street", "subdistrict", "vtc", "last_4_digits_mobile_no"] -# self.details_v2 = ["email_mobile_status", "referenceid", "name", "dob", "gender", "careof", "district", "landmark", -# "house", "location", "pincode", "postoffice", "state", "street", "subdistrict", "vtc"] -# self.delimiter = [-1] -# self.data = {} -# self._convert_base10encoded_to_decompressed_array() -# self._detect_version_and_adjust_details() -# self._create_delimiter() -# self._extract_info_from_decompressed_array() - -# def _convert_base10encoded_to_decompressed_array(self) -> None: -# bytes_array = self.base10encodedstring.to_bytes(5000, 'big').lstrip(b'\x00') -# print(f"Bytes array (trimmed leading zeros): {bytes_array[:100]}") # Debugging: print the first 100 bytes -# try: -# self.decompressed_array = zlib.decompress(bytes_array, 16 + zlib.MAX_WBITS) -# except Exception as e: -# print(f"Decompression error: {e}") -# return -# print(f"Decompressed array: {self.decompressed_array[:100]}") # Debugging: print the first 100 bytes of decompressed array - -# def _detect_version_and_adjust_details(self) -> None: -# # Check for version in the first two bytes -# version = self.decompressed_array[:2].decode("ISO-8859-1") -# if version.startswith('V'): -# # Version is present, use the details list with version -# self.details = self.details_v1 -# else: -# # Version is not present, use the details list without version -# self.details = self.details_v2 - -# def _create_delimiter(self) -> None: -# for i in range(len(self.decompressed_array)): -# if self.decompressed_array[i] == 255: -# self.delimiter.append(i) -# print(f"Delimiters: {self.delimiter}") - -# def _extract_info_from_decompressed_array(self) -> None: -# for i in range(len(self.details)): -# if i + 1 < len(self.delimiter): -# start_idx = self.delimiter[i] + 1 -# end_idx = self.delimiter[i + 1] -# self.data[self.details[i]] = self.decompressed_array[start_idx:end_idx].decode("ISO-8859-1") - -# print(f"Extracted data before verification: {self.data}") - -# referenceid = self.data.get('referenceid', '') -# if len(referenceid) >= 4: -# self.data['aadhaar_last_4_digit'] = referenceid[:4] -# self.data['aadhaar_last_digit'] = referenceid[3] -# else: -# print(f"Reference ID is too short: {referenceid}") -# print(f"Extracted data: {self.data}") - -# self.data['email'] = False -# self.data['mobile'] = False -# email_mobile_status = self.data.get('email_mobile_status', '') -# if email_mobile_status.isdigit(): -# email_mobile_status = int(email_mobile_status) -# if email_mobile_status in {3, 1}: -# self.data['email'] = True -# if email_mobile_status in {3, 2}: -# self.data['mobile'] = True - -# def decodeddata(self) -> dict: -# return self.data - -# def signature(self) -> bytes: -# return self.decompressed_array[len(self.decompressed_array) - 256:] - -# def signedData(self) -> bytes: -# return self.decompressed_array[:len(self.decompressed_array) - 256] - -# def isMobileNoRegistered(self) -> bool: -# return self.data['mobile'] - -# def isEmailRegistered(self) -> bool: -# return self.data['email'] - -# def sha256hashOfEMail(self) -> str: -# tmp = "" -# email_mobile_status = self.data.get('email_mobile_status', '') -# if email_mobile_status.isdigit() and int(email_mobile_status) == 3: -# tmp = self.decompressed_array[len(self.decompressed_array) - 256 - 32 - 32:len(self.decompressed_array) - 256 - 32].hex() -# elif email_mobile_status.isdigit() and int(email_mobile_status) == 1: -# tmp = self.decompressed_array[len(self.decompressed_array) - 256 - 32:len(self.decompressed_array) - 256].hex() -# return tmp - -# def sha256hashOfMobileNumber(self) -> str: -# email_mobile_status = self.data.get('email_mobile_status', '') -# if email_mobile_status.isdigit() and int(email_mobile_status) in {3, 2}: -# return self.decompressed_array[len(self.decompressed_array) - 256 - 32: len(self.decompressed_array) - 256].hex() -# return "" - -# def isImage(self, buffer=10) -> bool: -# email_mobile_status = self.data.get('email_mobile_status', '') -# if email_mobile_status.isdigit(): -# if int(email_mobile_status) == 3: -# return len(self.decompressed_array[self.delimiter[len(self.details)] + 1:]) >= 256 + 32 + 32 + buffer -# elif int(email_mobile_status) in {2, 1}: -# return len(self.decompressed_array[self.delimiter[len(self.details)] + 1:]) >= 256 + 32 + buffer -# elif int(email_mobile_status) == 0: -# return len(self.decompressed_array[self.delimiter[len(self.details)] + 1:]) >= 256 + buffer -# return False - -# def image(self) -> Union[Image.Image, None]: -# email_mobile_status = self.data.get('email_mobile_status', '') -# if email_mobile_status.isdigit() and int(email_mobile_status) in {0, 1, 2, 3}: -# return Image.open(BytesIO(self.decompressed_array[self.delimiter[len(self.details)] + 1:])) -# return None - -# def saveimage(self, filepath: str) -> None: -# image = self.image() -# if image: -# image.load() -# image.save(filepath) +import zlib +from io import BytesIO +from PIL import Image, ImageFile +ImageFile.LOAD_TRUNCATED_IMAGES = True +import base64 +import zipfile +import xml.etree.ElementTree as ET +from typing import Union +from pyaadhaar import utils + +class AadhaarSecureQr: + def __init__(self, base10encodedstring: str) -> None: + self.base10encodedstring = base10encodedstring + self.details_v1 = ["version", "email_mobile_status", "referenceid", "name", "dob", "gender", "careof", "district", "landmark", + "house", "location", "pincode", "postoffice", "state", "street", "subdistrict", "vtc", "last_4_digits_mobile_no"] + self.details_v2 = ["email_mobile_status", "referenceid", "name", "dob", "gender", "careof", "district", "landmark", + "house", "location", "pincode", "postoffice", "state", "street", "subdistrict", "vtc"] + self.delimiter = [-1] + self.data = {} + self._convert_base10encoded_to_decompressed_array() + self._detect_version_and_adjust_details() + self._create_delimiter() + self._extract_info_from_decompressed_array() + + def _convert_base10encoded_to_decompressed_array(self) -> None: + bytes_array = self.base10encodedstring.to_bytes(5000, 'big').lstrip(b'\x00') + print(f"Bytes array (trimmed leading zeros): {bytes_array[:100]}") # Debugging: print the first 100 bytes + try: + self.decompressed_array = zlib.decompress(bytes_array, 16 + zlib.MAX_WBITS) + except Exception as e: + print(f"Decompression error: {e}") + return + print(f"Decompressed array: {self.decompressed_array[:100]}") # Debugging: print the first 100 bytes of decompressed array + + def _detect_version_and_adjust_details(self) -> None: + # Check for version in the first two bytes + version = self.decompressed_array[:2].decode("ISO-8859-1") + if version.startswith('V'): + # Version is present, use the details list with version + self.details = self.details_v1 + else: + # Version is not present, use the details list without version + self.details = self.details_v2 + + def _create_delimiter(self) -> None: + for i in range(len(self.decompressed_array)): + if self.decompressed_array[i] == 255: + self.delimiter.append(i) + print(f"Delimiters: {self.delimiter}") + + def _extract_info_from_decompressed_array(self) -> None: + for i in range(len(self.details)): + if i + 1 < len(self.delimiter): + start_idx = self.delimiter[i] + 1 + end_idx = self.delimiter[i + 1] + self.data[self.details[i]] = self.decompressed_array[start_idx:end_idx].decode("ISO-8859-1") + + print(f"Extracted data before verification: {self.data}") + + referenceid = self.data.get('referenceid', '') + if len(referenceid) >= 4: + self.data['aadhaar_last_4_digit'] = referenceid[:4] + self.data['aadhaar_last_digit'] = referenceid[3] + else: + print(f"Reference ID is too short: {referenceid}") + print(f"Extracted data: {self.data}") + + self.data['email'] = False + self.data['mobile'] = False + email_mobile_status = self.data.get('email_mobile_status', '') + if email_mobile_status.isdigit(): + email_mobile_status = int(email_mobile_status) + if email_mobile_status in {3, 1}: + self.data['email'] = True + if email_mobile_status in {3, 2}: + self.data['mobile'] = True + + def decodeddata(self) -> dict: + return self.data + + def signature(self) -> bytes: + return self.decompressed_array[len(self.decompressed_array) - 256:] + + def signedData(self) -> bytes: + return self.decompressed_array[:len(self.decompressed_array) - 256] + + def isMobileNoRegistered(self) -> bool: + return self.data['mobile'] + + def isEmailRegistered(self) -> bool: + return self.data['email'] + + def sha256hashOfEMail(self) -> str: + tmp = "" + email_mobile_status = self.data.get('email_mobile_status', '') + if email_mobile_status.isdigit() and int(email_mobile_status) == 3: + tmp = self.decompressed_array[len(self.decompressed_array) - 256 - 32 - 32:len(self.decompressed_array) - 256 - 32].hex() + elif email_mobile_status.isdigit() and int(email_mobile_status) == 1: + tmp = self.decompressed_array[len(self.decompressed_array) - 256 - 32:len(self.decompressed_array) - 256].hex() + return tmp + + def sha256hashOfMobileNumber(self) -> str: + email_mobile_status = self.data.get('email_mobile_status', '') + if email_mobile_status.isdigit() and int(email_mobile_status) in {3, 2}: + return self.decompressed_array[len(self.decompressed_array) - 256 - 32: len(self.decompressed_array) - 256].hex() + return "" + + def isImage(self, buffer=10) -> bool: + email_mobile_status = self.data.get('email_mobile_status', '') + if email_mobile_status.isdigit(): + if int(email_mobile_status) == 3: + return len(self.decompressed_array[self.delimiter[len(self.details)] + 1:]) >= 256 + 32 + 32 + buffer + elif int(email_mobile_status) in {2, 1}: + return len(self.decompressed_array[self.delimiter[len(self.details)] + 1:]) >= 256 + 32 + buffer + elif int(email_mobile_status) == 0: + return len(self.decompressed_array[self.delimiter[len(self.details)] + 1:]) >= 256 + buffer + return False + + def image(self) -> Union[Image.Image, None]: + email_mobile_status = self.data.get('email_mobile_status', '') + if email_mobile_status.isdigit() and int(email_mobile_status) in {0, 1, 2, 3}: + return Image.open(BytesIO(self.decompressed_array[self.delimiter[len(self.details)] + 1:])) + return None + + def saveimage(self, filepath: str) -> None: + image = self.image() + if image: + image.load() + image.save(filepath) -# def contains_image(self) -> bool: -# return self.isImage() + def contains_image(self) -> bool: + return self.isImage() -# class AadhaarOldQr: -# # This is the class for Adhaar Normal Qr code.. In this version of code the data is in XML v1.0 format -# # For more information check here : https://103.57.226.101/images/resource/User_manulal_QR_Code_15032019.pdf - -# def __init__(self, qrdata): -# self.qrdata = qrdata -# self.xmlparser = ET.XMLParser(encoding="utf-8") -# self.parsedxml = ET.fromstring(qrdata, parser=self.xmlparser) -# self.data = self.parsedxml.attrib - -# def decodeddata(self): -# # Will return the decoded datas inn dictionary format -# return self.data - - -# class AadhaarOfflineXML: - -# # This is the class for Adhaar Offline XML -# # The special thing of Offline XML is that we can extract the high quality photo of user from the data -# # For more information check here : https://103.57.226.101/images/resource/User_manulal_QR_Code_15032019.pdf - -# def __init__(self, file, passcode): -# # Need to pass the zip file and passcode/sharecode to this function -# self.passcode = passcode -# self.data = {} -# zf = zipfile.ZipFile(file, 'r') -# zf.setpassword(str(self.passcode).encode('utf-8')) -# filedata = zf.open(zf.namelist()[0]).read() -# parsedxml = ET.fromstring( -# filedata, parser=ET.XMLParser(encoding="utf-8")) -# self.root = parsedxml - -# self.hashofmobile = self.root[0][0].attrib['m'] -# self.hashofemail = self.root[0][0].attrib['e'] - -# if self.hashofmobile != "" and self.hashofemail != "": -# self.data['email_mobile_status'] = "3" -# elif self.hashofmobile == "" and self.hashofemail != "": -# self.data['email_mobile_status'] = "2" -# elif self.hashofmobile != "" and self.hashofemail == "": -# self.data['email_mobile_status'] = "1" -# elif self.hashofmobile == "" and self.hashofemail == "": -# self.data['email_mobile_status'] = "0" - -# self.data['referenceid'] = self.root.attrib['referenceId'] -# self.data['name'] = self.root[0][0].attrib['name'] -# self.data['dob'] = self.root[0][0].attrib['dob'] -# self.data['gender'] = self.root[0][0].attrib['gender'] -# self.data['careof'] = self.root[0][1].attrib['careof'] -# self.data['district'] = self.root[0][1].attrib['dist'] -# self.data['landmark'] = self.root[0][1].attrib['landmark'] -# self.data['house'] = self.root[0][1].attrib['house'] -# self.data['location'] = self.root[0][1].attrib['loc'] -# self.data['pincode'] = self.root[0][1].attrib['pc'] -# self.data['postoffice'] = self.root[0][1].attrib['po'] -# self.data['state'] = self.root[0][1].attrib['state'] -# self.data['street'] = self.root[0][1].attrib['street'] -# self.data['subdistrict'] = self.root[0][1].attrib['subdist'] -# self.data['vtc'] = self.root[0][1].attrib['vtc'] -# self.data['adhaar_last_4_digit'] = self.data['referenceid'][0:4] -# self.data['adhaar_last_digit'] = self.data['referenceid'][3] - -# if self.data['email_mobile_status'] == "0": -# self.data['email'] = "no" -# self.data['mobile'] = "no" -# elif self.data['email_mobile_status'] == "1": -# self.data['email'] = "yes" -# self.data['mobile'] = "no" -# elif self.data['email_mobile_status'] == "2": -# self.data['email'] = "no" -# self.data['mobile'] = "yes" -# elif self.data['email_mobile_status'] == "3": -# self.data['email'] = "yes" -# self.data['mobile'] = "yes" - -# def decodeddata(self): -# # Will return data in dictionary format -# return self.data - -# def signature(self): -# # Will return the signature -# return self.root[1][1].text - -# def isMobileNoRegistered(self): -# # Will return True if mobile number is registered -# if int(self.data['email_mobile_status']) == 3 or int(self.data['email_mobile_status']) == 1: -# return True -# return False - -# def isEmailRegistered(self): -# # Will return True if email id is registered -# if int(self.data['email_mobile_status']) == 3 or int(self.data['email_mobile_status']) == 2: -# return True -# return False - -# def sha256hashOfEMail(self): -# # Will return the hash of the email id -# return self.hashofemail - -# def sha256hashOfMobileNumber(self): -# # Will return the hash of mobile number -# return self.hashofmobile - -# def image(self): -# # Will return the image stream to be used in another function -# img = self.root[0][2].text -# img = Image.open(BytesIO(base64.b64decode(img))) -# return img - -# def saveimage(self, filename): -# # Will save the image of user -# image = self.image() -# image.save(filename) - -# def contains_image(self) -> bool: -# try: -# img_data = self.root[0][2].text -# if img_data: -# Image.open(BytesIO(base64.b64decode(img_data))) -# return True -# except Exception as e: -# print(f"Error checking image: {e}") -# return False - -# def verifyEmail(self, emailid): -# # Will return True if emailid match with the given email id -# generated_sha_mail = utils.SHAGenerator( -# str(emailid)+str(self.passcode), self.data['adhaar_last_digit']) -# if generated_sha_mail == self.sha256hashOfEMail(): -# return True -# else: -# return False - -# def verifyMobileNumber(self, mobileno): -# # Will return True if mobileno match with the given mobile no -# generated_sha_mobile = utils.SHAGenerator( -# str(mobileno)+str(self.passcode), self.data['adhaar_last_digit']) -# if generated_sha_mobile == self.sha256hashOfMobileNumber(): -# return True -# else: -# return False +class AadhaarOldQr: + # This is the class for Adhaar Normal Qr code.. In this version of code the data is in XML v1.0 format + # For more information check here : https://103.57.226.101/images/resource/User_manulal_QR_Code_15032019.pdf + + def __init__(self, qrdata): + self.qrdata = qrdata + self.xmlparser = ET.XMLParser(encoding="utf-8") + self.parsedxml = ET.fromstring(qrdata, parser=self.xmlparser) + self.data = self.parsedxml.attrib + + def decodeddata(self): + # Will return the decoded datas inn dictionary format + return self.data + + +class AadhaarOfflineXML: + + # This is the class for Adhaar Offline XML + # The special thing of Offline XML is that we can extract the high quality photo of user from the data + # For more information check here : https://103.57.226.101/images/resource/User_manulal_QR_Code_15032019.pdf + + def __init__(self, file, passcode): + # Need to pass the zip file and passcode/sharecode to this function + self.passcode = passcode + self.data = {} + zf = zipfile.ZipFile(file, 'r') + zf.setpassword(str(self.passcode).encode('utf-8')) + filedata = zf.open(zf.namelist()[0]).read() + parsedxml = ET.fromstring( + filedata, parser=ET.XMLParser(encoding="utf-8")) + self.root = parsedxml + + self.hashofmobile = self.root[0][0].attrib['m'] + self.hashofemail = self.root[0][0].attrib['e'] + + if self.hashofmobile != "" and self.hashofemail != "": + self.data['email_mobile_status'] = "3" + elif self.hashofmobile == "" and self.hashofemail != "": + self.data['email_mobile_status'] = "2" + elif self.hashofmobile != "" and self.hashofemail == "": + self.data['email_mobile_status'] = "1" + elif self.hashofmobile == "" and self.hashofemail == "": + self.data['email_mobile_status'] = "0" + + self.data['referenceid'] = self.root.attrib['referenceId'] + self.data['name'] = self.root[0][0].attrib['name'] + self.data['dob'] = self.root[0][0].attrib['dob'] + self.data['gender'] = self.root[0][0].attrib['gender'] + self.data['careof'] = self.root[0][1].attrib['careof'] + self.data['district'] = self.root[0][1].attrib['dist'] + self.data['landmark'] = self.root[0][1].attrib['landmark'] + self.data['house'] = self.root[0][1].attrib['house'] + self.data['location'] = self.root[0][1].attrib['loc'] + self.data['pincode'] = self.root[0][1].attrib['pc'] + self.data['postoffice'] = self.root[0][1].attrib['po'] + self.data['state'] = self.root[0][1].attrib['state'] + self.data['street'] = self.root[0][1].attrib['street'] + self.data['subdistrict'] = self.root[0][1].attrib['subdist'] + self.data['vtc'] = self.root[0][1].attrib['vtc'] + self.data['adhaar_last_4_digit'] = self.data['referenceid'][0:4] + self.data['adhaar_last_digit'] = self.data['referenceid'][3] + + if self.data['email_mobile_status'] == "0": + self.data['email'] = "no" + self.data['mobile'] = "no" + elif self.data['email_mobile_status'] == "1": + self.data['email'] = "yes" + self.data['mobile'] = "no" + elif self.data['email_mobile_status'] == "2": + self.data['email'] = "no" + self.data['mobile'] = "yes" + elif self.data['email_mobile_status'] == "3": + self.data['email'] = "yes" + self.data['mobile'] = "yes" + + def decodeddata(self): + # Will return data in dictionary format + return self.data + + def signature(self): + # Will return the signature + return self.root[1][1].text + + def isMobileNoRegistered(self): + # Will return True if mobile number is registered + if int(self.data['email_mobile_status']) == 3 or int(self.data['email_mobile_status']) == 1: + return True + return False + + def isEmailRegistered(self): + # Will return True if email id is registered + if int(self.data['email_mobile_status']) == 3 or int(self.data['email_mobile_status']) == 2: + return True + return False + + def sha256hashOfEMail(self): + # Will return the hash of the email id + return self.hashofemail + + def sha256hashOfMobileNumber(self): + # Will return the hash of mobile number + return self.hashofmobile + + def image(self): + # Will return the image stream to be used in another function + img = self.root[0][2].text + img = Image.open(BytesIO(base64.b64decode(img))) + return img + + def saveimage(self, filename): + # Will save the image of user + image = self.image() + image.save(filename) + + def contains_image(self) -> bool: + try: + img_data = self.root[0][2].text + if img_data: + Image.open(BytesIO(base64.b64decode(img_data))) + return True + except Exception as e: + print(f"Error checking image: {e}") + return False + + def verifyEmail(self, emailid): + # Will return True if emailid match with the given email id + generated_sha_mail = utils.SHAGenerator( + str(emailid)+str(self.passcode), self.data['adhaar_last_digit']) + if generated_sha_mail == self.sha256hashOfEMail(): + return True + else: + return False + + def verifyMobileNumber(self, mobileno): + # Will return True if mobileno match with the given mobile no + generated_sha_mobile = utils.SHAGenerator( + str(mobileno)+str(self.passcode), self.data['adhaar_last_digit']) + if generated_sha_mobile == self.sha256hashOfMobileNumber(): + return True + else: + return False From b3fe01e660bbf9bdcca2e76432c4d6233e71c03d Mon Sep 17 00:00:00 2001 From: samruddhisk <153628687+samruddhisk@users.noreply.github.com> Date: Tue, 30 Jul 2024 16:06:39 +0530 Subject: [PATCH 3/4] New Updated decode.py --- pyaadhaar/decode.py | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/pyaadhaar/decode.py b/pyaadhaar/decode.py index 86d4f74..5e32d5b 100644 --- a/pyaadhaar/decode.py +++ b/pyaadhaar/decode.py @@ -9,6 +9,10 @@ from pyaadhaar import utils class AadhaarSecureQr: + # This is the class for Aadhaar Secure Qr code.. In this version of code the data is in encrypted format + # The special thing of this type of QR is that we can extract the photo of user from the data + # This class now supports 2022 version of Aadhaar QR codes [version-2] + # For more information check here : https://103.57.226.101/images/resource/User_manulal_QR_Code_15032019.pdf def __init__(self, base10encodedstring: str) -> None: self.base10encodedstring = base10encodedstring self.details_v1 = ["version", "email_mobile_status", "referenceid", "name", "dob", "gender", "careof", "district", "landmark", @@ -22,6 +26,7 @@ def __init__(self, base10encodedstring: str) -> None: self._create_delimiter() self._extract_info_from_decompressed_array() + # Converts base10encoded string to a decompressed array def _convert_base10encoded_to_decompressed_array(self) -> None: bytes_array = self.base10encodedstring.to_bytes(5000, 'big').lstrip(b'\x00') print(f"Bytes array (trimmed leading zeros): {bytes_array[:100]}") # Debugging: print the first 100 bytes @@ -42,12 +47,14 @@ def _detect_version_and_adjust_details(self) -> None: # Version is not present, use the details list without version self.details = self.details_v2 + # Creates the delimeter which is used to extract the information from the decompressed array def _create_delimiter(self) -> None: for i in range(len(self.decompressed_array)): if self.decompressed_array[i] == 255: self.delimiter.append(i) print(f"Delimiters: {self.delimiter}") + # Extracts the information from the decompressed array def _extract_info_from_decompressed_array(self) -> None: for i in range(len(self.details)): if i + 1 < len(self.delimiter): @@ -75,21 +82,27 @@ def _extract_info_from_decompressed_array(self) -> None: if email_mobile_status in {3, 2}: self.data['mobile'] = True + # Returns the extracted data in a dictionary format def decodeddata(self) -> dict: return self.data - + + # Returns signature of the QR code def signature(self) -> bytes: return self.decompressed_array[len(self.decompressed_array) - 256:] + + # Returns the signed data of the QR code def signedData(self) -> bytes: return self.decompressed_array[:len(self.decompressed_array) - 256] - + + # Check whether mobile no is registered or not def isMobileNoRegistered(self) -> bool: return self.data['mobile'] - + + # Check whether email id is registered or not def isEmailRegistered(self) -> bool: return self.data['email'] - + # Return hash of the email id def sha256hashOfEMail(self) -> str: tmp = "" email_mobile_status = self.data.get('email_mobile_status', '') @@ -98,13 +111,14 @@ def sha256hashOfEMail(self) -> str: elif email_mobile_status.isdigit() and int(email_mobile_status) == 1: tmp = self.decompressed_array[len(self.decompressed_array) - 256 - 32:len(self.decompressed_array) - 256].hex() return tmp - + # Return hash of the mobile number def sha256hashOfMobileNumber(self) -> str: email_mobile_status = self.data.get('email_mobile_status', '') if email_mobile_status.isdigit() and int(email_mobile_status) in {3, 2}: return self.decompressed_array[len(self.decompressed_array) - 256 - 32: len(self.decompressed_array) - 256].hex() return "" + # Check availability of image in the QR CODE def isImage(self, buffer=10) -> bool: email_mobile_status = self.data.get('email_mobile_status', '') if email_mobile_status.isdigit(): @@ -115,13 +129,13 @@ def isImage(self, buffer=10) -> bool: elif int(email_mobile_status) == 0: return len(self.decompressed_array[self.delimiter[len(self.details)] + 1:]) >= 256 + buffer return False - + # Return image stream def image(self) -> Union[Image.Image, None]: email_mobile_status = self.data.get('email_mobile_status', '') if email_mobile_status.isdigit() and int(email_mobile_status) in {0, 1, 2, 3}: return Image.open(BytesIO(self.decompressed_array[self.delimiter[len(self.details)] + 1:])) return None - + # Save the image of the user def saveimage(self, filepath: str) -> None: image = self.image() if image: @@ -131,6 +145,20 @@ def saveimage(self, filepath: str) -> None: def contains_image(self) -> bool: return self.isImage() + # Verify the email id + def verifyEmail(self, emailid:str) -> bool: + if type(emailid) != str: + raise TypeError("Email id should be string") + generated_sha_mail = utils.SHAGenerator(emailid, self.data['aadhaar_last_digit']) + return generated_sha_mail == self.sha256hashOfEMail() + + # Verify the mobile no + def verifyMobileNumber(self, mobileno:str) -> bool: + if type(mobileno) != str: + raise TypeError("Mobile number should be string") + generated_sha_mobile = utils.SHAGenerator(mobileno, self.data['aadhaar_last_digit']) + return generated_sha_mobile == self.sha256hashOfMobileNumber() + class AadhaarOldQr: # This is the class for Adhaar Normal Qr code.. In this version of code the data is in XML v1.0 format From c04a883edb51e68a554a7ac7b5452151c8b49a0c Mon Sep 17 00:00:00 2001 From: "deepsource-io[bot]" <42547082+deepsource-io[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 12:12:54 +0000 Subject: [PATCH 4/4] ci: add .deepsource.toml --- .deepsource.toml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .deepsource.toml diff --git a/.deepsource.toml b/.deepsource.toml new file mode 100644 index 0000000..0ac63d3 --- /dev/null +++ b/.deepsource.toml @@ -0,0 +1,7 @@ +version = 1 + +[[analyzers]] +name = "python" + + [analyzers.meta] + runtime_version = "3.x.x" \ No newline at end of file