Here’s my go at it. Similar to yours, except it does padding with zeroes at the end - seems to do the job well for arbitrary string legths.
StringEncryptor.h:
#ifndef __STRINGENCRYPTOR_H__
#define __STRINGENCRYPTOR_H__
#include "juce.h"
//==============================================================================
/**
A simple class for encrypting and decrypting string data types
Example:
@code
StringEncryptor se ("This is my key");
String enc = se.encryptString (String ("Password"));
AlertWindow::showMessageBox (AlertWindow::InfoIcon, "Blowfish encrypt", enc);
String temp = String (T("[")) + se.decryptString (enc) + String T("]") ;
AlertWindow::showMessageBox (AlertWindow::InfoIcon, "Blowfish decrypt", temp);
@endcode
*/
class StringEncryptor: public BlowFish
{
public:
/**
Initialise the encryptor with a key string, which will be used for
encryption and decryption as well.
@param strKey Encryption key
*/
StringEncryptor(const String& strKey);
/**
Default destructor.
*/
~StringEncryptor() {};
/**
Encrypt any non-empty string. The resulting string will be padded to the
nearest 16-character length.
@param str The string to encrypt
*/
const String encryptString (const String& str);
/**
Decrypt a previously encrypted string. Returns an empty string is the parameter
doesn't look like an encrypted string.
@param str The encrypted string we want to convert back
*/
const String decryptString (const String& str);
};
#endif // __STRINGENCRYPTOR_H__
StringEncryptor.cpp:
#include "StringEncryptor.h"
StringEncryptor::StringEncryptor(const String& strKey)
: BlowFish ((uint8 *)((const char *)strKey), strKey.length())
{
}
const String StringEncryptor::encryptString (const String& str)
{
if (!str.length())
return String::empty;
int iBlocksize = ((str.length()+7) / 8) * 8;
MemoryBlock mb (iBlocksize, true);
mb.copyFrom ((const char *)str, 0, str.length());
for (int n=0; n<iBlocksize/8; n++) {
encrypt ((uint32&)mb[n*8], (uint32&)mb[n*8+4]);
}
String strEncrypted = String::empty;
for (int i = 0; i<iBlocksize; i++) {
strEncrypted << String::formatted (T("%02x"), (unsigned char)mb[i]);
}
return strEncrypted;
}
const String StringEncryptor::decryptString (const String& str)
{
// If encrypted string is empty or it the length is not
// multiples of 16, something is wrong
if (!str.length() || (str.length() % 16))
return String::empty;
int iBlocksize = str.length() / 2;
// Make sure there's a \0 at the end of the string converted from mb
MemoryBlock mb (iBlocksize+1, true);
for (int i = 0; i<str.length()/2; i++) {
mb[i] = (char)(str.substring (i*2, i*2+2).getHexValue32());
}
for (int n=0; n<iBlocksize/8; n++) {
decrypt ((uint32&)mb[n*8], (uint32&)mb[n*8+4]);
}
return String::createStringFromData (mb.getData(), iBlocksize+1);
}
