import sys

def read_lsb(byte):
    """Extracts the least significant bit from a byte."""
    return byte & 0x01

def bytes_to_int(byte_list):
    """Converts a list of bytes to an integer."""
    result = 0
    for bit in byte_list:
        result = (result << 1) | bit
    return result

def extract_hidden_data(input_file, output_file):
    try:
        with open(input_file, "rb") as f:
            # Skip the first 100 bytes as they don’t contain hidden info
            f.seek(100)
            
            # Read bytes and process indicator
            indicator = []
            for _ in range(64):
                byte = f.read(1)
                if not byte:  # Check if the byte is empty (end of file)
                    raise ValueError("Reached end of file unexpectedly while reading indicator.")
                indicator.append(read_lsb(byte[0]))  # Directly use byte[0] as it’s already an integer
                
            indicator_value = bytes_to_int(indicator)
            if indicator_value != 0xa5a5a5a5a5a5a5a5:
                raise ValueError("No steganographic indicator found or incorrect sequence.")

            # Process the size of the hidden data
            size_bits = []
            for _ in range(27):
                byte = f.read(1)
                if not byte:
                    raise ValueError("Reached end of file unexpectedly while reading size.")
                size_bits.append(read_lsb(byte[0]))  # Directly use byte[0]
                
            hidden_size = bytes_to_int(size_bits)

            # Extract the hidden data
            hidden_data = []
            for _ in range(hidden_size * 8):
                byte = f.read(1)
                if not byte:
                    raise ValueError("Reached end of file unexpectedly while reading hidden data.")
                hidden_data.append(read_lsb(byte[0]))

            # Convert bits to bytes
            hidden_bytes = []
            for i in range(0, len(hidden_data), 8):
                byte = bytes_to_int(hidden_data[i:i+8])
                hidden_bytes.append(byte)

            # Write the extracted hidden data to the output file
            with open(output_file, "wb") as out:
                out.write(bytearray(hidden_bytes))

    except Exception as e:
        print(f"Failed to extract hidden data: {e}")

def main():
    if len(sys.argv) != 3:
        print("Usage: ./extract_stego.py <input_file> <output_file>")
        sys.exit(1)

    input_file, output_file = sys.argv[1], sys.argv[2]
    extract_hidden_data(input_file, output_file)
    print(f"Hidden data extracted to {output_file}.")

if __name__ == "__main__":
    main() For this programming task, your objective is to develop a program capable of extracting hidden information from a BMP image file
1. Initial State: The first 100 bytes of the BMP file do not contain any hidden (steganographic) information and should be ignored.
2. Identification of Stego Information:
• Data Extraction: The steganographic data is embedded in the least significant bit (LSB) of each byte in the file, starting after the initial 100 bytes. The less significant bits of each hidden bytes comes first in the bits sequence. To help you understand this, here’s an example: suppose the next 8 bits sequence that you read from the file are(in the order you get them) b0:0, b1:1, b2:1, b3:0, b4:1, b5:1, b6:0, b7:1. Based on this bits sequence where the MSB(b7)=1 and LSB(b0)=0, the reconstructed byte value is 0xb6 in hexadecimal and 182 in decimal.
• Indicator bits: Immediately following the initial 100 bytes, search for an 64 bits sequence in the hidden information where each interpreted byte is the hexadecimal value 0xa5. This sequence serves as a marker indicating the presence of steganographic content.
• Output Size: Directly after the indicator bits, the next 27 bits in the hidden information represent the size of the extracted information, in bytes. This size does not include the initial 100 bytes, the 64 bits indicator, or the 27 bits used for the size itself.
3. Extraction Process: Continue extracting the least significant bits from subsequent bytes, up to the number of bytes specified by the decoded size value. Collect the extracted bits and compile them into bytes to reconstruct the hidden data. The output should be saved to a file, the name/path of which will be specified via the command line.
Your program must accept the following inputs from the command-line: The name of the input file and the name of the output file. A command-line example: ./your_prog input_file output_file
Your program should handle any unexpected input correctly, e.g., invalid inputs, non-stegan files. check if the given program has all the requirements as specified and make any changes if necessary to incesase the efficiency of the code