281 lines
8.1 KiB
C++
281 lines
8.1 KiB
C++
/*
|
|
* steghide 0.5.1 - a steganography program
|
|
* Copyright (C) 1999-2003 Stefan Hetzl <shetzl@chello.at>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
*/
|
|
|
|
#ifndef SH_BITSTRING_H
|
|
#define SH_BITSTRING_H
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
#include "AUtils.h"
|
|
#include "common.h"
|
|
|
|
/**
|
|
* \class BitString
|
|
* \brief a string of bits
|
|
*
|
|
* This class provides a way to conveniently store and
|
|
* manipulate a string of bits. Various objects can be
|
|
* appended to a BitString.
|
|
*
|
|
* For data storage a vector of BYTEs is used with little
|
|
* endian bit encoding, i.e. the first bit is the least
|
|
* significant bit of the first byte and so on.
|
|
**/
|
|
class BitString {
|
|
public:
|
|
/**
|
|
* construct an empty BitString
|
|
**/
|
|
BitString (EmbValue arity = 2) ;
|
|
|
|
/**
|
|
* copy constructor
|
|
**/
|
|
BitString (const BitString& bs) ;
|
|
|
|
/**
|
|
* construct a BitString containing l bits with value zero
|
|
**/
|
|
BitString (const unsigned long l) ;
|
|
|
|
/**
|
|
* construct a BitString containing the data in d
|
|
**/
|
|
BitString (const std::vector<BYTE>& d) ;
|
|
|
|
/**
|
|
* construct a BitString containing the characters in d as 8 bit unsigned chars
|
|
**/
|
|
BitString (const std::string& d) ;
|
|
|
|
void setArity (EmbValue arity) ;
|
|
|
|
EmbValue getArity (void) const
|
|
{ return Arity ; } ;
|
|
|
|
/**
|
|
* get the number of bits in this BitString
|
|
**/
|
|
UWORD32 getLength (void) const
|
|
{ return Length ; } ;
|
|
|
|
/**
|
|
* get the number of EmbValues in this BitString (using this BitString's arity)
|
|
**/
|
|
UWORD32 getNAryLength (void) const
|
|
{ return AUtils::div_roundup<UWORD32> (Length, ArityNBits) ; } ;
|
|
|
|
/**
|
|
* delete the contents of this Bitstring
|
|
**/
|
|
BitString& clear (void) ;
|
|
|
|
/**
|
|
* append the bit v to this BitString
|
|
**/
|
|
BitString& append (const BIT v) ;
|
|
|
|
/**
|
|
* append n lower order bits of v to this BitString
|
|
* \param v the value to be appended
|
|
* \param n the number of bits to be appended
|
|
**/
|
|
BitString& append (const BYTE v, const unsigned short n = 8) ;
|
|
|
|
/**
|
|
* append n lower order bits of v to this BitString
|
|
* \param v the value to be appended
|
|
* \param n the number of bits to be appended
|
|
**/
|
|
BitString& append (const UWORD16 v, const unsigned short n = 16) ;
|
|
|
|
/**
|
|
* append n lower order bits of v to this BitString
|
|
* \param v the value to be appended
|
|
* \param n the number of bits to be appended
|
|
**/
|
|
BitString& append (const UWORD32 v, const unsigned short n = 32) ;
|
|
|
|
/**
|
|
* append the string v to this BitString
|
|
**/
|
|
BitString& append (const std::string& v) ;
|
|
|
|
/**
|
|
* append the vector v byte-wise to this BitString
|
|
**/
|
|
BitString& append (const std::vector<BYTE>& v) ;
|
|
|
|
/**
|
|
* append the BitString v to this BitString
|
|
* \param v the BitString to be appended
|
|
**/
|
|
BitString& append (const BitString& v) ;
|
|
|
|
/**
|
|
* set the p-th bit to v
|
|
* \param i the index (must be < getLength())
|
|
* \param v the value
|
|
**/
|
|
BitString& setBit (unsigned long i, BIT v) ;
|
|
|
|
/**
|
|
* get a BitString that is a part of this BitString
|
|
* \param s the index of the first bit to be copied from this BitString
|
|
* \param l the total number of bits to be used for the return value
|
|
* \return the BitString containing of the bits [s...s+(l-1)] of this BitString
|
|
**/
|
|
BitString getBits (const unsigned long s, const unsigned long l) const ;
|
|
|
|
/**
|
|
* cut some bits out of this BitString
|
|
* \param s the index of the first bit to be removed from this BitString
|
|
* \param l the total number of bits to be removed
|
|
* \return the BitString containing of the bits [s...s+(l-1)] of this BitString
|
|
*
|
|
* After calling cutBits, this BitString consists of the bits 0,...,s-1,s+l,... .
|
|
**/
|
|
BitString cutBits (const unsigned long s, const unsigned long l) ;
|
|
|
|
/**
|
|
* return a value composed from bits in this BitString
|
|
* \param s the index of the first bit to be used for the return value
|
|
* \param l the total number of bits to be used for the return value (must be <= 32)
|
|
* \return the value (*this)[s],...,(*this)[s+l-1]
|
|
**/
|
|
UWORD32 getValue (const unsigned long s, const unsigned short l) const ;
|
|
|
|
/**
|
|
* get the contents of this BitString as vector of bytes
|
|
* \return the contents of this BitString as vector of bytes
|
|
*
|
|
* getLength() % 8 must be 0 to call this function
|
|
**/
|
|
const std::vector<BYTE>& getBytes (void) const ;
|
|
|
|
/**
|
|
* truncate this BitString
|
|
* \param s start
|
|
* \param e end
|
|
* \return this BitString modified to contain only (*this)[s]...(*this)[e - 1]
|
|
**/
|
|
BitString& truncate (const unsigned long s, const unsigned long e) ;
|
|
|
|
/**
|
|
* pad this BitString with the value in v
|
|
* \param mult this BitString is padded until size is a multiple of mult (given in bits)
|
|
* \param v the value this BitString should be padded with
|
|
**/
|
|
BitString& pad (const unsigned long mult, const BIT v) ;
|
|
|
|
/**
|
|
* pad this BitString with random data
|
|
* \param mult this BitString is padded until size is a multiple of mult (given in bits)
|
|
**/
|
|
BitString& padRandom (const unsigned long mult) ;
|
|
|
|
/**
|
|
* get an n-ary digit from this BitString
|
|
* \param p the position (in the n-ary representation of this BitString)
|
|
* \return the p-th n-ary digit
|
|
**/
|
|
BYTE getNAry (unsigned long p) const ;
|
|
|
|
/**
|
|
* append an n-ary digit to this BitString
|
|
* \param v the n-ary value to be appended
|
|
**/
|
|
void appendNAry (BYTE v) ;
|
|
|
|
#ifdef USE_ZLIB
|
|
/**
|
|
* compress this BitString using zlib's compress2 function
|
|
* \param level the compression level (ranging from 1 (best speed) to 9 (best compression)
|
|
*
|
|
* As zlib operates on byte vectors and not on bit vectors, this BitString is padded
|
|
* with zeros until the next byte boundary before starting the compression.
|
|
**/
|
|
BitString& compress (int level) ;
|
|
|
|
/**
|
|
* uncompress this BitString using zlib's uncompress function
|
|
* \param idestlen the length of the uncompressed data (in bits)
|
|
* \return this BitString modified to contain exactly idestlen uncompressed bits
|
|
*
|
|
* idestlen must be the size of the uncompressed data (in bits) to make
|
|
* it possible to allocate a destination buffer and to give information
|
|
* about the length of the uncompressed data without padding.
|
|
*
|
|
* A precondition for calling this function is that this BitString actually
|
|
* contains data that has been compressed by the BitString::compress function,
|
|
* and especially that the Length % 8 is 0.
|
|
**/
|
|
BitString& uncompress (unsigned long idestlen) ;
|
|
#endif // def USE_ZLIB
|
|
|
|
/**
|
|
* get the value of the i-th bit
|
|
**/
|
|
BIT operator[] (const unsigned long i) const ;
|
|
|
|
/**
|
|
* xor v with this BitString, saving the result in this Bitstring.
|
|
* The result has the same length as this BitString.
|
|
**/
|
|
BitString& operator^= (const BitString &v) ;
|
|
|
|
/**
|
|
* compare this BitString with the BitString v
|
|
* \return true iff the lengths are equal and for every valid index the value is equal
|
|
**/
|
|
bool operator== (const BitString& v) const ;
|
|
|
|
/**
|
|
* compare this BitString with the BitString v
|
|
* \return true iff the lengths are not equal or there exists an index with different values
|
|
**/
|
|
bool operator!= (const BitString& v) const ;
|
|
|
|
void print (unsigned short spc = 0) const ;
|
|
#ifdef DEBUG
|
|
void printDebug (unsigned short level, unsigned short spc = 0) const ;
|
|
#endif
|
|
|
|
private:
|
|
/// the number of bits in Data
|
|
UWORD32 Length ;
|
|
/// the arity that will be used for getLength/getNAry/appendNAry
|
|
EmbValue Arity ;
|
|
/// the number of Bits per n-ary digit (where n is Arity)
|
|
unsigned short ArityNBits ;
|
|
/// the actual data
|
|
std::vector<BYTE> Data ;
|
|
|
|
void _append (BIT v) ;
|
|
|
|
/**
|
|
* clear unused part of last byte (_append depends on this)
|
|
**/
|
|
void clearUnused (void) ;
|
|
} ;
|
|
|
|
#endif // ndef SH_BITSTRING_H
|