Bases: BaseCodec
This algorithm write the content of the txt text
document to the midi audio. MIDI-stegano is a Python program that allows
you to hide some message in a MIDI file. The size of the message depends
on the characteristics of the MIDI file, more precisely depends on the
number of notes within the file.
- Created by: QiuYu
- Created time: 2022/12/05
Originally implemented in
Masanar/MIDI-steganography
Source code in stegobox/codec/midi_stegano.py
| class MIDIStegano(BaseCodec):
"""This algorithm write the content of the txt text
document to the midi audio. MIDI-stegano is a Python program that allows
you to hide some message in a MIDI file. The size of the message depends
on the characteristics of the MIDI file, more precisely depends on the
number of notes within the file.
* Created by: QiuYu
* Created time: 2022/12/05
Originally implemented in
[Masanar/MIDI-steganography](https://github.com/Masanar/MIDI-steganography)
"""
def __init__(self) -> None:
super().__init__()
def midi_csv(self, filename):
csv_string = filename
count = 0
for i in csv_string:
line = i.strip().split(", ")
if line[2] == "Note_on_c" or line[2] == "Note_off_c":
count += 1
return csv_string, count
def csv_midi(self, csv_file):
return csv_file
def hide(self, csv_string, bits):
csv_hide = []
count = 0
countloop = 0
while countloop < len(csv_string):
message = csv_string[countloop]
new = message.strip().split(", ")
if new[2] == "Note_on_c":
if int(new[5]) < 10:
new[5] = bits[count]
else:
new[5] = new[5][:-1] + bits[count]
count += 1
csv_hide.append((", ".join(new) + "\n"))
countloop += 1
if count == len(bits):
break
csv_hide += csv_string[countloop:]
return csv_hide
def encode(self, carrier: list, payload: str) -> list:
"""Encoder requires carrier audio to be MID and payload to be a txt document.
Args:
carrier: Carrier audio in format MID. Read with `stegobox.io.midi.read()`.
payload: Payload (secret message) to be encoded. Payload in format TXT.
Read with `stegobox.io.txt.read_bytes()`
Returns:
csv_file: Generate audio using `stegobox.io.midi.write()`.
"""
csv, size = self.midi_csv(carrier)
text = payload
bits = " ".join(format(ord(x), "b") for x in text)
lbits = len(bits.replace(" ", ""))
while lbits >= size:
print("\n \nThe text is too big for hide in the file")
print("Give me the text you want to hide in the MIDI file \n")
text = payload
bits = " ".join(format(ord(x), "b") for x in text)
lbits = len(bits.replace(" ", ""))
csv_hide = self.hide(csv, bits.replace(" ", ""))
print("\n****************The message was sucefully hide****************")
csv_file = self.csv_midi(csv_hide)
return csv_file
# unhide(csv_hide)
def decode(self, carrier: list) -> str:
"""Decode the secret payload from the carrier audio
Args:
carrier: Carrier audio in format MID. Read with `stegobox.io.midi.read()`.
Returns:
message: The decoded payload (secret message).
"""
csv_hide, _ = self.midi_csv(carrier)
message_bits = ""
countloop = 0
while countloop < len(csv_hide):
message = csv_hide[countloop]
new = message.strip().split(", ")
if new[2] == "Note_on_c":
if int(new[5]) < 10:
if int(new[5]) > 1:
break
else:
message_bits += new[5]
else:
if int(new[5][-1]) > 1:
break
else:
message_bits += new[5][-1]
countloop += 1
message = self.decodebits(message_bits)
return message[:-1]
def decodebits(self, message_bits):
message = ""
for j in range(0, len(message_bits) - 1, 7):
message += chr(int(message_bits[j : j + 7], 2))
print("**************************************************************\n")
print("The message hide in the .midi file is:", message)
print("**************************************************************\n")
return message
|
encode(carrier, payload)
Encoder requires carrier audio to be MID and payload to be a txt document.
Parameters:
Name |
Type |
Description |
Default |
carrier |
list
|
Carrier audio in format MID. Read with stegobox.io.midi.read() .
|
required
|
payload |
str
|
Payload (secret message) to be encoded. Payload in format TXT.
Read with stegobox.io.txt.read_bytes()
|
required
|
Returns:
Name | Type |
Description |
csv_file |
list
|
Generate audio using stegobox.io.midi.write() .
|
Source code in stegobox/codec/midi_stegano.py
| def encode(self, carrier: list, payload: str) -> list:
"""Encoder requires carrier audio to be MID and payload to be a txt document.
Args:
carrier: Carrier audio in format MID. Read with `stegobox.io.midi.read()`.
payload: Payload (secret message) to be encoded. Payload in format TXT.
Read with `stegobox.io.txt.read_bytes()`
Returns:
csv_file: Generate audio using `stegobox.io.midi.write()`.
"""
csv, size = self.midi_csv(carrier)
text = payload
bits = " ".join(format(ord(x), "b") for x in text)
lbits = len(bits.replace(" ", ""))
while lbits >= size:
print("\n \nThe text is too big for hide in the file")
print("Give me the text you want to hide in the MIDI file \n")
text = payload
bits = " ".join(format(ord(x), "b") for x in text)
lbits = len(bits.replace(" ", ""))
csv_hide = self.hide(csv, bits.replace(" ", ""))
print("\n****************The message was sucefully hide****************")
csv_file = self.csv_midi(csv_hide)
return csv_file
|
decode(carrier)
Decode the secret payload from the carrier audio
Parameters:
Name |
Type |
Description |
Default |
carrier |
list
|
Carrier audio in format MID. Read with stegobox.io.midi.read() .
|
required
|
Returns:
Name | Type |
Description |
message |
str
|
The decoded payload (secret message).
|
Source code in stegobox/codec/midi_stegano.py
| def decode(self, carrier: list) -> str:
"""Decode the secret payload from the carrier audio
Args:
carrier: Carrier audio in format MID. Read with `stegobox.io.midi.read()`.
Returns:
message: The decoded payload (secret message).
"""
csv_hide, _ = self.midi_csv(carrier)
message_bits = ""
countloop = 0
while countloop < len(csv_hide):
message = csv_hide[countloop]
new = message.strip().split(", ")
if new[2] == "Note_on_c":
if int(new[5]) < 10:
if int(new[5]) > 1:
break
else:
message_bits += new[5]
else:
if int(new[5][-1]) > 1:
break
else:
message_bits += new[5][-1]
countloop += 1
message = self.decodebits(message_bits)
return message[:-1]
|