Example #1
0
    def __recover_message(self, mediate_length, key):
        """
        After extraction is completed, call this method to decode and extract original message.
        :param mediate_length: the mediate length of hidden message (necessary to perform decoding)
        :return: extracted message
        """

        if not mediate_length:
            mediate_length = mediate_length
            if mediate_length <= 0:
                raise AttributeError('Necessary argument not specified!')

        if len(self.message_to_proc_part) > mediate_length:
            self.message_to_proc_part = self.message_to_proc_part[:mediate_length]
        elif len(self.message_to_proc_part) < mediate_length:
            raise RuntimeError("Couldn't extract message with provided argument.")

        # print self.message_to_proc_part.tolist()

        s = int(math.ceil(math.sqrt(len(self.message_to_proc_part) / StegoCore.BITS)))
        try:
            msg_matrix_encoded_array = np.reshape(self.message_to_proc_part, (s, s, StegoCore.BITS))
        except ValueError:
            print colorize("Wrong session key. Can't extract message.", COLORS.FAIL)
            return ''

        msg_matrix_encoded = sh.bits_matrix_to_int_matrix(msg_matrix_encoded_array)
        msg_matrix = QMatrix.decode_matrix_message(msg_matrix_encoded, key)
        msg = sh.matrix_to_message(msg_matrix)
        return msg
Example #2
0
 def __configure_for_stream_mode(self, stream_mode, **kwargs):
     """
     Configure session for specified stream mode
     :param stream_mode:
     :param kwargs:
     :return:
     """
     print "Configurating..."
     self.stream_mode = stream_mode
     if stream_mode == StreamMode.StreamFromFileToFile:
         # file to file
         input = kwargs[KEY_INPUT_FILE_NAME]
         self.stego_mode = kwargs[KEY_STEGO_MODE]
         self.file_source = wave.open(input, 'rb')
         if self.stego_mode == StegoMode.Hide:
             self.output_wave_file = wave.open(kwargs[KEY_OUTPUT_FILE_NAME],
                                               'wb')
             self.output_wave_file.setnchannels(
                 self.file_source.getnchannels())
             self.output_wave_file.setsampwidth(
                 self.file_source.getsampwidth())
             self.output_wave_file.setframerate(
                 self.file_source.getframerate())
         self.enable_processing = True
     elif stream_mode == StreamMode.StreamFromBuildInInputToSoundFlower:
         # build-in input to sound flower
         self.stego_mode = StegoMode.Hide
     elif stream_mode == StreamMode.StreamFromSoundFlowerToBuildInOutput:
         # sound flower to build-in output
         self.stego_mode = StegoMode.Recover
     else:
         print colorize("Unsupported stream mode! [%i]" % self.stream_mode,
                        COLORS.FAIL)
Example #3
0
 def __hide(self, chunk_source, chunk_container):
     """
     Hide message part in container
     :param chunk: chunk to be used as container
     :return:      processed or the original chunk
     """
     container_processed, self.message_to_proc_part = self.gsc.hide(chunk_source, chunk_container, self.message_to_proc_part)
     if not len(self.message_to_proc_part):
         print colorize("Message integrated.", COLORS.OKBLUE)
     return chunk_source, container_processed
Example #4
0
 def scan(self):
     """
     Begin synchronization and message extraction.
     """
     if not (self.stream_mode
             == StreamMode.StreamFromSoundFlowerToBuildInOutput
             or self.stream_mode == StreamMode.StreamFromFileToFile):
         print colorize("Not applicable for current stream mode!",
                        COLORS.FAIL)
         return
     print colorize("Begin scanning...", COLORS.OKGREEN)
     self.enable_processing = True
Example #5
0
 def deserialize(self, filename=SETTINGS_FILE_NAME):
     if os.path.isfile(filename):
             with open(filename, 'r') as infile:
                 data = json.load(infile)
                 self.frames_to_skip = data[SETTING_KEY_FRAMES_TO_SKIP]
                 self.frame_size = data[SETTINGS_KEY_FRAME_SIZE]
                 self.sync_mark = data[SETTINGS_KEY_SYNC_MARK]
                 self.security_or_capacity = data[SETTINGS_SECURITY_OR_CAPACITY]
                 self.build_in_input_audio_device_name = data[SETTINGS_KEY_BUILD_IN_INPUT]
                 self.build_in_output_audio_device_name = data[SETTINGS_KEY_BUILD_IN_OUTPUT]
                 self.virtual_audio_device_name = data[SETTINGS_KEY_VIRTUAL_DEVICE]
     else:
         print colorize("%s couldn't be found. Applying default settings." % SETTINGS_FILE_NAME, COLORS.FAIL)
         self.serialize()
         self.deserialize()
Example #6
0
    def do_connect(self, line):
        """
        Create session with specified mode.

        usage:
            connect m=<mode>&d=<debug>

        :param mode:
            0 - record sound from mic, hide message and redirect it to SoundFlower virtual device
            1 - receive sound from  SoundFlower virtual device, recover message and play it in dynamics
        :param debug
            0 - false (default)
            1 - true
        """
        args = urlparse.parse_qs(line)
        try:
            mode = int(args['m'][0])
        except KeyError:
            mode = 0
        try:
            self.debug = bool(args['d'][0])
            if self.debug:
                print colorize("Debug mode.", COLORS.WARNING)
        except KeyError:
            pass
        if not (mode == StreamMode.StreamFromBuildInInputToSoundFlower
                or mode == StreamMode.StreamFromSoundFlowerToBuildInOutput):
            self.print_err(inspect.currentframe().f_code.co_name.replace(
                'do_', ''))
            return

        # load settings
        settings = StegoSettings.Instance()
        settings.deserialize()
        if settings.validate_stream_mode(mode):
            self.session = StegoScramblerSession(
                mode, **{
                    StegoCore.SYNC_MARK_KEY: settings.sync_mark,
                    StegoCore.SECURITY_OR_CAPACITY:
                    settings.security_or_capacity
                })
            self.session.open_stream()
        else:
            print colorize(
                "There are no supported audio devices for current stream mode.",
                COLORS.FAIL)
Example #7
0
 def recover(self, session_key, user_key, msg_file_name):
     """
     Extract and decode message, save it to file
     :param session_key:
     :param user_key:
     :return:
     """
     if not (self.stream_mode
             == StreamMode.StreamFromSoundFlowerToBuildInOutput
             or self.stream_mode == StreamMode.StreamFromFileToFile):
         print colorize("Not applicable for current stream mode!",
                        COLORS.FAIL)
         return
     message = self.core.recover(session_key, user_key)
     gs_io.save_message_to_file(msg_file_name, message)
     if not message == '':
         print colorize("Message recovered.", COLORS.OKGREEN)
Example #8
0
    def __init__(self, stego_mode, **kwargs):
        """
        Init core class instance.

        :param stego_mode:  StegoMode.Hide or StegoMode.Recover
        :param kwargs:
                            1) StegoMode.Hide    - necessary keys:
                                a) StegoCore.SKIP_FRAMES_KEY - number of frames to skip before integration  [optional]
                                b) StegoCore.SYNC_MARK_KEY - text marker to perform synchronization         [optional]
                            2) StegoMode.Recover - optional key:
                                a) StegoCore.SKIP_FRAMES_KEY - number of frames to skip before integration  [optional]
                                b) StegoCore.SYNC_MARK_KEY - text marker to perform synchronization         [optional]
        """

        self.stego_mode = stego_mode    # encode or decode
        self.message_to_proc_part = np.empty(0, dtype=np.int8)    # the part of message that left to be integrated
        self.skip_frames = 0            # how many frames shoud be skipped
        self.mediate_length = 0         # length of message to recover (length of bits array)
        self.security_or_capacity = 0
        # synchronization
        self.sync_mark = ''                 # synchronization mark
        self.sync_mark_encoded_array = np.empty(0, dtype=np.int8)   # synchronization mark encoded
        self.sync_mark_temp_encoded_array = []  # list that may contain sync mark
        if stego_mode == StegoMode.Hide:
            if StegoCore.SKIP_FRAMES_KEY in kwargs:
                # set number of frames to skip
                self.skip_frames = kwargs[StegoCore.SKIP_FRAMES_KEY]
        else:
            if StegoCore.SKIP_FRAMES_KEY in kwargs:
                # set number of frames to skip
                self.skip_frames = kwargs[StegoCore.SKIP_FRAMES_KEY]

        if StegoCore.SYNC_MARK_KEY in kwargs:
            self.sync_mark = kwargs[StegoCore.SYNC_MARK_KEY]
            self.__synchronization_prepare()

            if StegoCore.SECURITY_OR_CAPACITY in kwargs:
                self.security_or_capacity = kwargs[StegoCore.SECURITY_OR_CAPACITY]

            self.gsc = gsc_core.PyCore(self.sync_mark_encoded_array, 1024, 3 * 1024, self.security_or_capacity)
        else:
            print colorize("Error: no sync mark provided", COLORS.FAIL)
Example #9
0
 def hide(self,
          msg_file_name,
          key,
          recover_info_filename=RECOVER_INFO_DEFAULT_FILE_NAME):
     """
     Load message and call core method to begin integration.
     :param msg_file_name: file name of the file with message
     :param key:           key to encode message
     """
     if not (self.stream_mode
             == StreamMode.StreamFromBuildInInputToSoundFlower
             or self.stream_mode == StreamMode.StreamFromFileToFile):
         print colorize("Not applicable for current stream mode!",
                        COLORS.FAIL)
     # load mesage
     message = gs_io.load_message_from_file(msg_file_name)
     if not message == '':
         print colorize("Begin integration...", COLORS.OKBLUE)
         session_key = self.core.hide(message, key)
         gs_io.save_data_to_recover(recover_info_filename, session_key)
         self.enable_processing = True
     else:
         print colorize("Wrong or empty file with message!", COLORS.FAIL)
Example #10
0
 def print_err(self, fa_name):
     print colorize("Wrong arguments. Type `help " + fa_name + "`",
                    COLORS.FAIL)
Example #11
0
 def __init__(self):
     cmd.Cmd.__init__(self)
     self.session = None
     self.debug = False
     print colorize("Welcome!", COLORS.WARNING)
Example #12
0
def main(opts):
    input_container_file_name = ''
    message_file_name = ''
    output_container_file_name = ''
    key = -1
    message_length = -1
    recover_info_file_name = RECOVER_INFO_DEFAULT_FILE_NAME
    # --------------------------------------
    # print colorize("Debug mode.", COLORS.WARNING)
    # # --------------------------------------
    # hide = True
    # #hide = False
    # # --------------------------------------
    # if hide:
    #     # --------------------------------------
    #     input_container_file_name = "wav/input.wav"
    #     message_file_name = "data/msg.txt"
    #     output_container_file_name = "wav/output.wav"
    #     key = 7
    #     recover_info_file_name = "data/recover_info.txt"
    #     # --------------------------------------
    # else:
    #     # --------------------------------------
    #     input_container_file_name = "wav/output.wav"
    #     message_file_name = "data/msg_recovered.txt"
    #     key = 7
    #     recover_info_file_name = "data/recover_info.txt"
    #     # --------------------------------------
    # --------------------------------------
    for opt, arg in opts:
        if opt == '-h':
            print_usage()
            sys.exit()
        elif opt in ("-i", "--ifile"):
            input_container_file_name = arg
        elif opt in ("-m", "--mfile"):
            message_file_name = arg
        elif opt in ("-o", "--ofile"):
            output_container_file_name = arg
        elif opt in ("-k", "--key"):
            key = int(arg)
        elif opt in ("-l", "--length"):
            message_length = int(arg)
        elif opt in ("-r", "--recover_info"):
            recover_info_file_name = arg

    if input_container_file_name == '' or message_file_name == '':
        print_usage()
        sys.exit()

    if not output_container_file_name == '':
        # --------------------------------------
        # hide
        # --------------------------------------
        # load settings
        settings = StegoSettings.Instance()
        settings.deserialize()
        if settings.validate_stream_mode(StreamMode.StreamFromFileToFile):
            stego_session = StegoScramblerSession(
                StreamMode.StreamFromFileToFile, **{
                    KEY_STEGO_MODE: StegoMode.Hide,
                    KEY_INPUT_FILE_NAME: input_container_file_name,
                    KEY_OUTPUT_FILE_NAME: output_container_file_name,
                    StegoCore.SKIP_FRAMES_KEY: settings.frames_to_skip,
                    StegoCore.SYNC_MARK_KEY: settings.sync_mark,
                    StegoCore.SECURITY_OR_CAPACITY:
                    settings.security_or_capacity
                })
            stego_session.open_stream()
            stego_session.hide(message_file_name, key)
        else:
            print "There are no supported audio devices for current stream mode."
        # --------------------------------------
    else:
        if message_length <= 0:
            message_length = gs_io.load_data_to_recover(recover_info_file_name)
        if message_length > 0:
            # --------------------------------------
            # recover
            # --------------------------------------
            # load settings
            settings = StegoSettings.Instance()
            settings.deserialize()
            if settings.validate_stream_mode(StreamMode.StreamFromFileToFile):
                stego_session = StegoScramblerSession(
                    StreamMode.StreamFromFileToFile, **{
                        KEY_STEGO_MODE:
                        StegoMode.Recover,
                        KEY_INPUT_FILE_NAME:
                        input_container_file_name,
                        StegoCore.SKIP_FRAMES_KEY:
                        settings.frames_to_skip,
                        StegoCore.SYNC_MARK_KEY:
                        settings.sync_mark,
                        StegoCore.SECURITY_OR_CAPACITY:
                        settings.security_or_capacity
                    })
                stego_session.open_stream()
                stego_session.scan()
            else:
                print "There are no supported audio devices for current stream mode."
            # --------------------------------------
        else:
            print_usage()
            sys.exit()

    try:
        while stego_session.stream.is_active():
            time.sleep(0.1)
    except KeyboardInterrupt:
        pass
    finally:
        if stego_session.stego_mode == StegoMode.Recover:
            session_key = gs_io.load_data_to_recover(recover_info_file_name)
            try:
                stego_session.recover(session_key, key, message_file_name)
            except AttributeError:
                pass
            except ValueError:
                pass
            except RuntimeError:
                pass
        stego_session.close_stream()
        print colorize('Done!', COLORS.WARNING)
    sys.exit(0)
Example #13
0
    def open_stream(self):
        # instantiate PyAudio
        self.p_audio = pyaudio.PyAudio()
        if self.stream_mode == StreamMode.StreamFromFileToFile:
            print colorize("Opening file stream...", COLORS.WARNING)
            # file to file
            format, channels, rate = self.p_audio.get_format_from_width(self.file_source.getsampwidth()), \
                                     self.file_source.getnchannels(), self.file_source.getframerate()
            input_dev_idx = gs_device_info.detect_build_in_input_device_idx(
                self.p_audio)
            output_dev_idx = gs_device_info.detect_build_in_output_device_idx(
                self.p_audio)
            enable_input, enable_output = False, True
        elif self.stream_mode == StreamMode.StreamFromBuildInInputToSoundFlower:
            print colorize("Opening stream...", COLORS.OKBLUE)
            # build-in input to sound flower
            format, channels, rate = FORMAT, CHANNELS, RATE
            input_dev_idx = gs_device_info.detect_build_in_input_device_idx(
                self.p_audio)
            output_dev_idx = gs_device_info.detect_virtual_audio_device_idx(
                self.p_audio)
            enable_input, enable_output = True, True
        elif self.stream_mode == StreamMode.StreamFromSoundFlowerToBuildInOutput:
            print colorize("Opening stream...", COLORS.OKGREEN)
            # sound flower to build-in output
            format, channels, rate = FORMAT, CHANNELS, RATE
            input_dev_idx = gs_device_info.detect_virtual_audio_device_idx(
                self.p_audio)
            output_dev_idx = gs_device_info.detect_build_in_output_device_idx(
                self.p_audio)
            enable_input, enable_output = True, True
        else:
            print colorize("Unsupported stream mode! [%i]" % self.stream_mode,
                           COLORS.FAIL)
            raise ValueError("Unsupported stream mode! [%i]" %
                             self.stream_mode)

        settings = StegoSettings.Instance()

        print colorize("Input device: %i" % input_dev_idx, COLORS.WARNING)
        print colorize("Output device: %i" % output_dev_idx, COLORS.WARNING)
        print colorize(
            "Format: {0}, Channels: {1}, Rate: {2}, Frame size: {3}".format(
                format, channels, rate, settings.frame_size), COLORS.WARNING)
        # standard L-R stereo
        channel_map = (0, 1)
        try:
            stream_info = pyaudio.PaMacCoreStreamInfo(
                flags=pyaudio.PaMacCoreStreamInfo.paMacCorePlayNice,  # default
                channel_map=channel_map)
        except AttributeError:
            print colorize(
                "Sorry, couldn't find PaMacCoreStreamInfo. Make sure that "
                "you're running on OS X.", COLORS.FAIL)
            sys.exit(-1)

        if gs_device_info.validate_audio_setup(self.p_audio, format, channels,
                                               rate, input_dev_idx):
            self.stream = self.p_audio.open(
                format=format,
                channels=channels,
                rate=rate,
                frames_per_buffer=settings.frame_size,
                input=enable_input,
                output=enable_output,
                output_host_api_specific_stream_info=stream_info,
                input_device_index=input_dev_idx,
                output_device_index=output_dev_idx,
                stream_callback=self.__recording_callback)
            self.stream.start_stream()

            src_latency = 1000.0 * self.stream.get_input_latency()
            buffer_latency = 1000.0 * settings.frame_size / rate
            dst_latency = 1000.0 * self.stream.get_output_latency()
            total_latency = buffer_latency + dst_latency + src_latency
            print colorize(
                "Expected delay: %0.1f ms (src: %0.1f, buf: %0.1f, dst: %0.1f)"
                % (total_latency, src_latency, buffer_latency, dst_latency),
                COLORS.WARNING)
        else:
            print colorize("Unsupported audio configuration!", COLORS.FAIL)
            raise ValueError("Unsupported audio configuration!")