Tuesday, August 25, 2009

A Steganography Tool

Check my cute little creation ;)

Stegosaurus 1.0 is a tool to perform steganography on 24-bit BMP files.

Use this to hide and recover any type of file to and from a selected BMP image, without altering the original size of the image

For details of the steganography process used visit

http://www.garykessler.net/library/steganography.html

A Combination Generator Class

//The Combination Generator Class
#include < vector >
using namespace std;

typedef unsigned long long uint64;

class CombinationGenerator
{
public:
CombinationGenerator(int, int);
uint64 getNumLeft() const;
bool hasMore() const;
uint64 getTotal() const;
vector getNext();

private:
void reset();
uint64 getFactorial(int) const;

vector indices;
int n, r;
uint64 numLeft, total;
};

//--------------------------------------------
//The Constructor: Arguments n and r of nCr
//--------------------------------------------
CombinationGenerator::CombinationGenerator(int n, int r)
{
if (r > n || n <>n = n;
this->r = r;
indices.resize(r);
uint64 nFact = getFactorial (n);
uint64 rFact = getFactorial (r);
uint64 nminusrFact = getFactorial (n - r);
total = nFact/(rFact*nminusrFact);

reset ();

}
//------
// Reset
//------
void CombinationGenerator::reset()
{
for (int i = 0; i < numleft =" total;" style="color: rgb(0, 153, 0);">//------------------------------------------------
// Return number of combinations not yet generated
//------------------------------------------------
uint64 CombinationGenerator::getNumLeft() const
{
return numLeft;
}
//-----------------------------
// Are there more combinations?
//-----------------------------
bool CombinationGenerator::hasMore() const
{
return numLeft>0;
}
//------------------------------------
// Return total number of combinations
//------------------------------------
uint64 CombinationGenerator::getTotal() const
{
return total;
}
//------------------
// Compute factorial
//------------------
uint64 CombinationGenerator::getFactorial(int n) const
{
uint64 fact =1;
for (int i = n; i > 1; i--) {
fact = fact*i;
}
return fact;
}
//--------------------------------------------------------
// Generate next combination
//--------------------------------------------------------
vector CombinationGenerator::getNext()
{
if (numLeft==total) {
numLeft = numLeft-1;
return indices;
}
int i = r - 1;
while (indices[i] == n - r + i) {
i--;
}
indices[i] = indices[i] + 1;
for (int j = i + 1; j < r; j++) {
indices[j] = indices[i] + j - i;
}
numLeft = numLeft-1;
return indices;
}

///////////////Test Program/////////////////////
#include < iostream >
#include "CombinationGenerator.h"
using namespace std;

int main()
{
int myints[] = {44,67,23,74};
vector myvector (myints, myints+4);

sort (myvector.begin(), myvector.end(), greater());

/////////Generate 4C3 combinations///////////////

CombinationGenerator x(myvector.size(), 3);
while (x.hasMore ()) {
vector indices = x.getNext ();
for (int i = 0; i < indices.size(); i++) {
cout << myvector[indices[i]] <<" ";
}
cout <<endl;
}
getchar();
return 0;
}

Download Source

Tuesday, March 24, 2009

Linux - Receiving daemon messages in your Mail Client Inbox

Daemon messages in Linux are mailed to the superuser. The good old command line utility mail always rocks to access these messages. But what if you wanted to receive these messages in your default mail client inbox and access them via GUI? The steps are really easy. I will show you how to do this configuring Thunderbird as my default mail client.

1. Download Mozilla Thunderbird on your Linux box.(The package will have a name like thunderbird.tar.gz)

2. Unzip the package using the following commands:
gunzip thunderbird.tar.gz

tar -xvf thunderbird.tar

3. Move thunderbird directory to the /opt directory.

4. Goto the /opt directory and run the application
cd /opt
./thunderbird

5. Follow the account setup instructions as shown:









(assuming you are root on the machine free.scoobydoo)








6. Click Finish and we are all set to go. The daemon messages from now onwards will be available in your inbox. Thunderbird will retrieve them from the system mbox, whenever it is started.

QSqlDatabase closing problem while using QSqlTableModel with QTableView

Problem:

I was working on a application that deals with multiple databases when I encountered a problem while closing a connection. Even if I close the connection it seemed to be active and hence was not letting itself to be copied.
The code I used typically was :

QSqlDatabase db(Conn);

....................................
....................................

....................................
db.close();



The copying problem caused due to the connection remaining active got solved after enclosing the queries in proper scope. eg.

{
QSqlDatabase db = QSqlDatabase::database("sales");
QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
}
// Both "db" and "query" are destroyed because they are out of scope
QSqlDatabase::removeDatabase("sales"); // correct

But the problem reappeared, after I implemented a QTableView with a QSqlTableModel:

QSqlTableModel *model =new QSqlTableModel(this, Conn) ;
model->setTable("student");
model->setFilter("student_id=" +QString::number(Cmn_Global::student_id ));
model->setSort(3, Qt::AscendingOrder);
model->setEditStrategy(QSqlTableModel:: OnFieldChange);
model->select();
............................
...........................
ui.tableView->setModel(model);//view is the QTableView object

Calling db.close() failed to close the connection as the real time querying between the Model and the View, which was not possible for me to enclose within scope.


Solution:
The only solution that emerged was to kill the connection manually, by deleting the QSqlTableModel pointer related to the view using the following code:
QSqlTableModel* model= dynamic_cast (ui.tableView->model());
delete model;

And then calling the close method on the database.

The database can then be smoothly copied as the connection was no more active.

Wednesday, March 4, 2009

Word Wrap Code

This is a code to wrap a QString if it exceeds a particular number of characters per line, without splitting any word into different lines.

Signature : QString wordWrap(const QString &str, int wrapLength)
Argument : 1. The QString to be wrapped
2. The permissible number of characters per line.

Return Value: The wrapped QString

QString wordWrap(const QString &str, int wrapLength)
{
QString tempStr= str;
int len = str.length(), pos= (wrapLength>1)?wrapLength -1:1;

while(pos < len-1){

int tempPos=pos;
while(tempStr.at(tempPos)!=' ' && tempPos > 0){

tempPos--;
}
if(tempPos > 0)pos=tempPos;

tempStr.replace(pos,1,'\n');
pos+=pos;
}

return tempStr;
}

Directory Copy code

This is a directory copy code . It copies all the files or subdirectories under the destination directory to the target directory:

Signature : void copyDir(QString, QString)
Argument : 1. Path of the source directory
2. Path of the destination directory (if the destination does not exist, it is created automatically)

Return Value: void

void copyDir(QString src, QString dest)
{
//Check whether the dir directory exists
if(QDir(src).exists()){
if(!QDir(dest).exists()){
QDir().mkpath(dest);
}

//Construct an iterator to get the entries in the directory
QDirIterator dirIterator(src);

while (dirIterator.hasNext()) {
QString item= dirIterator.next(), fileName= dirIterator.fileName();
QFileInfo fileInfo= dirIterator.fileInfo();

if(fileName!="." && fileName!=".."){

//If entry is a file copy it
if(fileInfo.isFile()){
QFile::copy(item, dest+"/"+ fileName);
}
//If entry is a directory, call the deltree function over it again to traverse it
else
copy(item, dest+ "/"+ fileName);
}
}
}else return;

}

Monday, March 2, 2009

Directory Tree Deletion Code (rmdir or rm -f equivalent)

This is a directory removal code (rm -r or rmdir equivalent). It deletes all the files or subdirectories under the directory pointed to and also deletes the directory itself:

Signature : bool delTree(QString)
Argument : Path of the directory to be deleted as QString
Return Value: true on success/false on error

bool delTree(QString dir)
{
//Check whether the dir directory exists
if(QDir(dir).exists()){

//Construct an iterator to get the entries in the directory
QDirIterator dirIterator(dir);

while (dirIterator.hasNext()) {

//Get the file information
QString item= dirIterator.next(), fileName= dirIterator.fileName();
QFileInfo fileInfo= dirIterator.fileInfo();

//If entry is a file delete it
if(fileName!="." && fileName!=".."){

if(fileInfo.isFile()){
QFile::remove(item);
}
//If entry is a directory, call the deltree function over it again to traverse it
else if(fileInfo.isDir()){
delTree(item);
}
}
}
}else
return false;

//Move up the directory hierarchy by one level
//Delete the current directory
QDir currentDir(dir);
currentDir.cdUp();
return currentDir.rmdir(dir);

}

Monday, February 23, 2009

QTreeWidgetItem coloring problem on Windows Vista

Problem:

http://www.qtsoftware.com/developer/task-tracker/index_html?method=entry&id=225056

Solved with Qt 4.5

I found out this problem while attempting to use the background coloring for a QTreeWidgetItem using the void QTreeWidgetItem::setBackground(int column, const QBrush & brush) method while programming on Vista. The problem is that the tree items only gets colored on mouse hover, else the color does not hold.

I have posted this problem long ago on the QtForums.org and then found out this to be an issue Qt has with Vista (http://www.qtsoftware.com/developer/task-tracker/index_html?method=entry&id=225056
). This issue has not been fixed yet.

Solution:
The workaround however seemed to be amazingly simple, though I came across it quite by an accident. All that is needed to get this method take its usual course on Vista is to set the Application Style to that of Windows XP. This can easily be achieved by calling QApplication::setStyle("WindowsXP") at the program initialization... maybe in the constructor.