⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stego.c

📁 mp3 source code decoder & encoder
💻 C
字号:
/*---------------------------------------------------------------------------
 * FILE			$Workfile: stego.c $ - Part of MP3 Stego
 *
 * AUTHOR		Copyright (c) 1998 - Fabien Petitcolas
 *                                   University of Cambridge
 *
 * PURPOSE		Encryption, compression and pseudo-random number functions for
 *              steganography. Header file.
 *
 * $Modtime: 9/02/99 21:56 $
 * $Revision: 6 $
 * $Header: /StegoLib/stego.c 6     9/02/99 22:26 Fapp2 $
 * $Log: /StegoLib/stego.c $
 * 
 * 6     9/02/99 22:26 Fapp2
 * Displays estimation of bits that can be hidden.
 * Support for passphrase as command line parameter.
 * 
 * 5     15/08/98 10:38 Fapp2
 * Started revision control on this file.
 * 
 * 5     15/08/98 10:36 Fapp2
 * Started revision control on this file.
 *---------------------------------------------------------------------------
 */

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>

#include "error.h"
#include "stego.h"
#include "tools.h"

#define STEGO_BUFFER_SIZE 5  /* Buffer size in bytes */

static FILE *fEmbeddedText = NULL;     /* File containing the hidden data */
static unsigned char *pBuffer = NULL;  /* Buffer                          */
static char pszTemp[256];              /* Name of temporary file that will*/
                                       /* be read or written by the stego */
char pszPassPhrase[MAX_LEN];           /* Passphrase for encryption and   */
                                       /* bit selection                   */
static size_t nBufferIndex = 0;        /* Byte index within the buffer    */
static size_t lData = 0;               /* Length of hidden data after     */
                                       /* compression and encryption      */

#if defined(_DEBUG) | defined(DEBUG) /* STEGO */
extern FILE *fLog = NULL;
//extern FILE *fEmbedded = NULL;
#endif /* STEGO */

/*---------------------------------------------------------------------------
 * Open the file that contains the data to be hidden, compress it and
 * and encrypt it in a temporary file
 *---------------------------------------------------------------------------
 */
void StegoOpenEmbeddedText(char *pszFileName, size_t nMaxHiddenBits)
{
    size_t nEmbed = 0, nDontEmbed = 0, nRandomBits = 0;

//#if defined(_DEBUG) | defined(DEBUG)
//    fEmbedded = fopen("Embedded_bits.txt", "wb");
//#endif
   
    strcpy(pszPassPhrase, ReadPassPhrase());

    GetTemporaryFileName(pszTemp);

    lData = CompressEncryptFile(pszFileName, pszTemp, pszPassPhrase, 1);

    GetPseudoRandomBit(RESET);
    while (nEmbed < (lData * 8))
    {
        if (GetPseudoRandomBit(NEXT) == EMBED)
            nEmbed++;
        else
            nDontEmbed++;
    }
    nRandomBits = nEmbed + nDontEmbed;
    GetPseudoRandomBit(RESET);

    if (nRandomBits > nMaxHiddenBits)
        ERROR("StegoOpenEmbeddedText: data file too long. You can hide roughly %d bits.", nMaxHiddenBits);

	if ((fEmbeddedText = fopen(pszTemp, "rb")) == NULL)
        ERROR("StegoOpenEmbeddedText: data file not found.");

#if defined(_DEBUG) | defined(DEBUG)
    printf("\n\n");
#endif
}

/*---------------------------------------------------------------------------
 * Returns the next bit to be hidden or '2' if nothing should be hidden      
 * at this location                                                          
 *---------------------------------------------------------------------------
 */
int StegoGetNextBit()
{
	unsigned char *p;
	static int bNeedMoreData = 1, bFinished = 0, bEOF = 0, bBody = 0;
	static size_t nBufferIndex, maxBufferIndex, nBitIndex;
	size_t nRead;
	int bit;
	
	if (fEmbeddedText)
	{
		if (bFinished)
			return 2;
        if (GetPseudoRandomBit(NEXT) != EMBED)
            return 2;
		if (pBuffer == NULL)
		{
			pBuffer = (unsigned char *)malloc(STEGO_BUFFER_SIZE);
			if (pBuffer == NULL)
                ERROR("StegoGetNextBit: not enough memory");
            memset(pBuffer, 0, STEGO_BUFFER_SIZE);
		}
        if (bBody == 0)
        {
            bBody = 1;
            memcpy(pBuffer, &lData, sizeof(lData));
            nRead = sizeof(lData);
            maxBufferIndex = nRead - 1;
            bNeedMoreData = 0;
        }
        if (bNeedMoreData)
		{
			nRead = fread(pBuffer, 1, STEGO_BUFFER_SIZE, fEmbeddedText);
			bEOF = feof(fEmbeddedText);
			if ((nRead < STEGO_BUFFER_SIZE) && !bEOF) 
                ERROR("StegoGetNextBit: error reading data file");
            if (nRead == 0)
            {
                bFinished = 1;
                return 2;
            }
            else
			    maxBufferIndex = nRead - 1;
			bNeedMoreData = 0;
		}
		p = pBuffer + nBufferIndex;
		bit = (int)((*p >> nBitIndex) & 0x1);
		nBitIndex = (nBitIndex + 1) % 8;
		if (nBitIndex == 0)
		{
			nBufferIndex = (nBufferIndex + 1) % (maxBufferIndex + 1);
			if (nBufferIndex == 0)
			{
				if (bEOF) /* then ther's no more data to embedd */
					bFinished = 1;
				else
					bNeedMoreData = 1;
			}
		}
//#if defined(_DEBUG) | defined(DEBUG)
//       fwrite(&bit, 1, 1, fEmbedded);
//#endif
		return bit;
	}
	return 2;
}

/*---------------------------------------------------------------------------
 * Close the compressed & encrypted data file and delete it                  
 *---------------------------------------------------------------------------
 */
void StegoCloseEmbeddedText()
{
//#if defined(_DEBUG) | defined(DEBUG)
     //  fclose(fEmbedded);
//#endif

    if (fclose(fEmbeddedText) != 0) ERROR("Data file not closed properly.");

    /* Tidy */
    if (pBuffer) free(pBuffer);
    memset(pszPassPhrase, 0, strlen(pszPassPhrase));
    remove(pszTemp);
}


/*---------------------------------------------------------------------------
 * Prepare the decoding
 *---------------------------------------------------------------------------
 */
void StegoCreateEmbeddedText(void)
{
//#if defined(_DEBUG) | defined(DEBUG)
  //  fEmbedded = fopen("Extracted_bits.txt", "wb");
//#endif
    strcpy(pszPassPhrase, ReadPassPhrase());
    GetPseudoRandomBit(RESET);
    GetTemporaryFileName(pszTemp);
    if ((fEmbeddedText = fopen(pszTemp, "wb")) == NULL)
        ERROR("StegoCreateEmbeddedText: could not create data file.\n");
}

/*---------------------------------------------------------------------------
 * Append new extracted bit to temporary file if this bit is selected
 * by the pseudo random bit generator
 *---------------------------------------------------------------------------
 */
void SaveHiddenBit(int bit)
{
	unsigned char *p;
	static int bFinished = 0, bBody = 0;
	static size_t nBitIndex;
	size_t nWritten;
    static size_t nSaved = 0;

	if (fEmbeddedText && !bFinished && (GetPseudoRandomBit(NEXT) == EMBED))
	{
//#if defined(DEBUG) | defined(_DEBUG)
  //      printf("%d", bit);
    //    fwrite(&bit, 1, 1, fEmbedded);
//#endif
		if (pBuffer == NULL)
		{
			pBuffer = (unsigned char *)malloc(STEGO_BUFFER_SIZE);
			if (pBuffer == NULL)
                ERROR("SaveHiddenBit: not enough memory\n");
			memset(pBuffer, 0, STEGO_BUFFER_SIZE);
		}
        
        if (bBody)
            if (++nSaved == (lData * 8))
                bFinished = 1;

		p = pBuffer + nBufferIndex;
		if (bit) *p |= (1 << nBitIndex);
		nBitIndex = (nBitIndex + 1) % 8;

		if (nBitIndex == 0)
		{
    		nBufferIndex = (nBufferIndex + 1) % STEGO_BUFFER_SIZE;
            if (bBody)
            {
                if (nBufferIndex == 0)
                {
                    /* Buffer is full */
			        nWritten = fwrite(pBuffer, 1, STEGO_BUFFER_SIZE, fEmbeddedText);
			        if (nWritten != STEGO_BUFFER_SIZE)
                        ERROR("SaveHiddenBit: error writting data file\n");
			        memset(pBuffer, 0, STEGO_BUFFER_SIZE);
                }
            }
            else
            {
                if (nBufferIndex == sizeof(lData))
                {
                    memcpy(&lData, pBuffer, sizeof(lData));
                    memset(pBuffer, 0, STEGO_BUFFER_SIZE);
                    bBody = 1;
                    nBufferIndex = nBitIndex = 0;
                }
            }
		}
	}
}

/*---------------------------------------------------------------------------
 * Finish decoding
 *---------------------------------------------------------------------------
 */
void StegoFlushEmbeddedText(char *pszFileName)
{
//#if defined(_DEBUG) | defined(DEBUG)
       //fclose(fEmbedded);
//#endif

	if (fEmbeddedText)
	{
		fwrite(pBuffer, 1, nBufferIndex, fEmbeddedText);
		if (fclose(fEmbeddedText) != 0)
            ERROR("StegoFlushEmbeddedText: data file not closed properly.\n");
                
        CompressEncryptFile(pszTemp, pszFileName, pszPassPhrase, 0);

        /* Tidy */
        if (pBuffer) free(pBuffer);
        memset(pszPassPhrase, 0, strlen(pszPassPhrase));
        remove(pszTemp);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -