C++ Extracting a character from an image using bit-wise operations - c++

this is my first time here asking a questions, so bear with me! I have a steganography lab that I am nearly complete with. I have completed a program that hides a message in the lower bits of an image, but the program to extract the image is where I am stuck. The image is in a file represented as a 2D matrix, column major order. So here is the code where I am stuck.
void image::reveal_message()
{
int bitcount = 0;
char c;
char *msg;
while(c != '\0' || bitcount < 1128)
{
for(int z = 0; z < cols; z++)
{
for(int k = 0; k < 8; k++)
{
int i = bitcount % rows ;
int j = bitcount / rows ;
int b = c & 1;
if(img[i][j] % 2 != 0 && b == 0)
{
c = c & (~1);
}
else if(img[i][j] % 2 == 0 && b == 1)
{
c = c | 1;
}
bitcount++;
c = c << 1;
}
reverse_bits(c);
cout << c << endl;
//strncat(msg, &c, 1);
}
}
int i = 0;
for(int i = 0; i < cols; i++)
{
if(!isprint(msg[i]))
{
cout << "There is no hidden message" << endl;
}
}
cout << "This is the hidden message" << endl;
cout << msg;
}
The code is able to loop through and grab all the right number for the bits. The bits are based on if the number in the matrix is odd or even. Where I am having trouble is actually setting the bits of the char to the bits the I extracted from the matrix. I am not the best at bit-wise operations, and we are also not supposed to use any library for this. The reverse_bits function works as well, so it seems to be just my shifting and bit-wise operations are messed up.I also commented out the strcat() line because it was producing a lot of errors due to the fact that char c is incorrect. Also the main error I keep receiving is Segmentation Dump.

My understanding from your code is that you embedded your message as 1 bit per pixel, row by row. For example, if you have a 3x10 image, with pixels
01 02 03 04 05 06 07 08 09 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
the first character of your message resides in the pixels 01-08, the second from 09 to 16, etc. After your message, you embedded an extra null character, which you can use during extraction to know when to stop. With all that in mind, you're looking for something like this.
int bitcount = 0;
int i = 0;
int j = 0;
while(bitcount < 1128)
{
// this will serve as the ordinal value for the extracted char
int b = 0;
for(int k = 0; k < 8; k++)
{
b = (b << 1) | (img[i][j] & 1);
j++;
if(j == cols)
{
i++;
j = 0;
}
}
bitcount += 8;
// do whatever you want with this, print it, store it somewhere, etc
c = (char)b;
if(c == '\0')
{
break;
}
}
Understanding how the bitshifting work. b starts with the value 0, or 00000000 if you would like to visualise it in binary. Every time, you shift it to the left by one to make room for the new extracted bit, which you OR. No need to check whether it's 1 or 0, it'll just work.
So, imagine you've extracted 5 bits so far, b is 00010011 and the least significant bit of the current image pixel is 1. What will happen is this
b = (b << 1) | 1 // b = 00100110 | 1 = 00100111
And thus you have extracted the 6th bit.
Now, let's say you embedded the character "a" (01100001) in the first 8 pixels.
01 02 03 04 05 06 07 08 \\ pixels
0 1 1 0 0 0 0 1 \\ least significant bit of each pixel
When you extract the bits with the above, b will equal to 97 and c will give you "a". However, if you embedded your bits in the reverse order, i.e.,
01 02 03 04 05 06 07 08 \\ pixels
1 0 0 0 0 1 1 0 \\ least significant bit of each pixel
you should change the extracting algorithm to the following so you won't have to reverse the bits later on
int b = 0;
for(int k = 7; k <= 0; k--)
{
b = b | ((img[i][j] & 1) << k);
// etc
}

You start with undefined data in your char c.
You read from it here int b = c & 1;.
That is clearly nonsense.
c = c <<1; // shift before, not after
// if odd clear:
if(img[i][j] % 2)
{
c = c & (~1);
}
else // if even set:
{
c = c | 1;
}
the above may not read the data, but at least is not nonesense.
The bitwise operations look otherwise fine.
char *msg; should be std::string, and use += instead of strncat.

Related

How to do a specific double "for" loop to do a calcul

I would like to be able to do a loop that be able to make a count like this :
00 01 02 03 04
10 11 12 13 14
20 12 22 23 24
30 31 32 33 34
40 41 42 43 44
The way they are wrote is not important, I just want to be able do a count from 0 to 4 on the right number, then it do a + to the left number, and again 0 to 4
And here is what I've done
for (i; i <= TAILLE - 1; i++) {
for (int i2=0; i2 <= TAILLE - 1; i2++) {
//tableau[x][y] = false;
cout << x << y << endl;
y = i2;
}
x = i;
}
TAILLE = 5
x=0
y=0
i=0
i2=0
x is the left number
y the right number
This should do the trick:
for (int i = 0; i < TAILLE; i++) {
for (int j=0; j <TAILLE; j++) {
cout << i << j << ' ';
}
cout << endl;
}
some notes on this code:
1.- Instead of i<=TAILLE -1 use i<TAILLE it is shorter and easier to read. Also it is more computationally efficient since you avoid the subtraction, this is very subtle, but it's good to note this kind of detail, since in large datasets this could mean saving thousands or millions of calculations.
2.- Use i, j, k instead of i, i2, i3, this is not mandatory, but is kind of the standard and makes it easier to read as well.
3.- The variables x and y are not necessary, you can use directly i and j

CRC32 C++ implementation using bool array and manually XORing bit by bit

I have problem with understanding how CRC32 should work in normal way.
I've implemented mechanism from wiki and other sites: https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Computation
where you xor elements bit by bit. For CRC32 I've used Polynomial from wiki, which is also everywhere:
x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
with binary representation: 1 0000 0100 1100 0001 0001 1101 1011 0111
I was calculating CRC32 for input string "1234" only for testing.
This is the output of program:
https://i.stack.imgur.com/tG4wk.png
as you can see the xor is calculated properly and CRC32 is "619119D1". When I calculate it using online calculator or even c++ boost lib, the answer is "9BE3E0A3".
What is wrong with normal XORing input string bit by bit? Should I add something at the end or what?
I don't want to use libs and any other magic code to compute this, because I have to implement it in that way for my study project.
I've tried also polynomial without x^32, negate bits at the end, starting from 1s instead of 0s (where you have to add 32 zeros), and the answer is also different. I have no idea what should I do now to fix this.
This is the part of the code (a bit changed), I have buffor 3parts * 32bits, I'm loading 4 Chars from file to the middle part and xor from beggining to the middle, at the end I xor the middle part and the end -> the end is CRC32.
My pseudo schema:
1) Load 8 chars
2) | First part | Middle Part | CRC32 = 0 |
3) XOR
4) | 0 0 0 0 | XXXXXXX | 0 0 0 0 |
5) memcpy - middle part to first part
6) | XXXXXXX | XXXXXXX | 0 0 0 0 |
7) Load 4 chars
8) | XXXXXXX | loaded 4chars | 0 0 0 0 |
9) repeat from point 4 to the end of file
10) now we have: | 0 0 0 0 | XXXXXX | 0 0 0 0 |
11) last xor from middle part to end
12) Result: | 0 0 0 0 | 0 0 0 0 | CRC32 |
Probably screen with output will be more helpful.
I will use smart pointers etc. later ;)
bool xorBuffer(unsigned char *buffer) {
bool * binaryTab = nullptr;
try {
// CRC-32
// 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
// 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 0 1 1 0 1 1 1
const int dividerSizeBits = 33;
const bool binaryDivider[dividerSizeBits] = { 1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,0,0,0,1,1,1,0,1,1,0,1,1,0,1,1,1 };
const int dividerLength = countLength(binaryDivider, dividerSizeBits);
const int dividerOffset = dividerSizeBits - dividerLength; // when divider < 33 bits
bool * binaryTab = charTabToBits(buffer);
// check tab if first part = 0
while (!checkTabIfEmpty(binaryTab)) {
// set the beginnning
int start = 0;
for (start = 0; start < 32; start++)
if (binaryTab[start] == true)
break;
for (int i = 0; i < dividerLength; i++)
binaryTab[i + start] = binaryTab[i + start] ^ binaryDivider[i + dividerOffset];
}
// binaryTab -> charTab
convertBinaryTabToCharTab(binaryTab, buffer);
}
catch (exception e) {
delete[] binaryTab;
return false;
}
delete[] binaryTab;
return true;
}
std::string CRC::countCRC(std::string fileName){
// create variables
int bufferOnePartSize = 4;
int bufferSize = bufferOnePartSize * 3;
bool EOFFlag = false;
unsigned char *buffer = new unsigned char[bufferSize];
for (int i = 0; i < 3 * bufferOnePartSize; i++)
buffer[i] = 0;
// open file
ifstream fin;
fin.open(fileName.c_str(), ios_base::in | ios_base::binary);
int position = 0;
int count = 0;
// while -> EOF
if (fin.is_open()) {
// TODO check if file <= 4 -> another solution
char ch;
int multiply = 2;
bool skipNormalXor = false;
while (true) {
count = 0;
if (multiply == 2)
position = 0;
else
position = bufferOnePartSize;
// copy part form file to tab
while (count < bufferOnePartSize * multiply && fin.get(ch)) {
buffer[position] = (unsigned char)ch;
++count;
++position;
}
cout << endl;
// if EOF write zeros to end of tab
if (count == 0) {
cout << "TODO: end of file" << endl;
EOFFlag = true;
skipNormalXor = true;
}
else if (count != bufferOnePartSize * multiply) {
for (int i = count; i < bufferOnePartSize * multiply; i++) {
buffer[position] = 0;
position++;
}
EOFFlag = true;
}
if (!skipNormalXor) {
// -- first part
multiply = 1;
// xor the buffer
xorBuffer(buffer);
}
if (EOFFlag) { // xor to the end
xorBuffer(buffer + bufferOnePartSize);
break;
}
else {
// copy memory
for (int i = 0; i < bufferOnePartSize; i++)
buffer[i] = buffer[i + bufferOnePartSize];
}
}
cout << "\n End\n";
fin.close();
}
stringstream crcSum;
for (int i = 2 * bufferOnePartSize; i < bufferSize; i++) {
//buffer[i] = ~buffer[i];
crcSum << std::hex << (unsigned int)buffer[i];
}
cout << endl << "CRC: " << crcSum.str() << endl;
delete[] buffer;
return crcSum.str();
}
A CRC is not defined by just the polynomial. You need to define the bit ordering, the initial value of the CRC register, and the final exclusive-or of the CRC. For the standard CRC-32, which gives 0x9be3e0a3 for "1234", the bits are processed starting with the least significant bit, the initial value of the register is 0xffffffff, and you exclusive-or the final results with 0xffffffff.

Array of Pointers getting garbage value in c++

I'm trying to create an array of pointers to a 2D (5 X 12) array in C++.
The ptr array has 5 elements. Each element should hold the address of the 1st element of the respective row of the 2D array. So 1st element should point to 1st element of 1st row, 2nd element should point to 1st element of 2nd row, and so on.
The 5th element of my array of pointers seems to point to a garbage value.
Code and output shown below. Can anyone please let me know why?
#include <iostream>
#include <cstdlib>
#include <iomanip>
using namespace std;
int main( )
{
int rainMatrix[5][12] = {{0}}; //declare and initialize rain matrix
int *matrix_ptr[5] = {NULL};//declare and initialize array of pointers
int **matrix_ptr_ptr = matrix_ptr;
for (int i = 0; i < 5; ++i)
matrix_ptr[i] = &rainMatrix[i][0];
rainGen(matrix_ptr_ptr, 5, 12); //generate a random matrix
//display the matrix
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 12; ++j) {
cout << setw(2) << rainMatrix[i][j] << " ";
}
cout << endl;
}
for (int i = 0; i < 5; ++i)
cout << setw(2) << *matrix_ptr[i] << " " << rainMatrix[i][0] << endl;
return 0;
}
void rainGen (int **pptr, int row, int col)
{
unsigned int seed = 43;
unsigned int rv;
srand(seed);
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
rv = rand() % 100;
**pptr = rv;
*pptr += 1;
}
pptr++;
}
}
OUTPUT
11 1
88 11
28 88
25 28
1477892712 25
You're manipulating the wrong pointer in the innermost loop. Consider the pointer arithmetic carefully:
pptr essentially points to matrix_ptr[0];
on the first iteration, the double indirection means **pptr will set what you want, but then
*pptr += 1 will modify the contents of matrix_ptr[0], which means it no longer points to the beginning of the matrix.
Subsequent passes through the loop compound the situation drastically.
Modifying pptr won't help because it actually points to the wrong thing: it points to matrix_ptr, so incrementing it merely once moves its address from that of matrix_ptr[0], which points to rainMatrix[0][0], to that of matrix_ptr[1], which points to rainMatrix[1][0]. That is the wrong address for the next entry of the matrix, which is rainMatrix[0][1]. In essence, you've moved to the next row, instead of to the next column.
Try this for the innermost loop instead:
for (int i = 0; i < row; ++i)
{
auto qptr = *pptr;
for (int j = 0; j < col; ++j)
{
rv = rand() % 100;
*qptr = rv;
qptr += 1;
}
pptr++;
}
}
In this case, qptr is given the address of the first entry in the matrix. *qptr = rv sets the value. qptr += 1 increments the position of qptr while leaving *pptr alone - and, by extension, it leaves matrix_ptr[0] alone.
John Perry correctly identified the problem, but you have several option to deal with it. You are incorrectly incrementing *pptr += 1 Beyond using auto, you can simply index the pointer with the offset of j, e.g.
*(*pptr + j) = rv;
or
(*pptr)[j] = rv;
Either will work. Putting it together in your rainGen function, you could do:
void rainGen (int **pptr, int row, int col)
{
unsigned int seed = 43;
unsigned int rv;
srand(seed);
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
rv = rand() % 100;
// *(*pptr + j) = rv; /* or */
(*pptr)[j] = rv;
}
pptr++;
}
}
(note: seed and srand(seed) should be moved to main() if there is the potential that rainGen could be called more than once -- srand should only be called once)
Example Use/Output
Both will produce the desired output:
$ ./bin/raingen
72 71 65 94 0 13 49 17 36 49 67 51
87 68 45 15 91 72 16 80 77 35 9 81
11 88 73 59 24 22 37 48 45 54 94 45
19 44 62 56 45 81 59 32 49 4 99 92
28 16 24 5 3 34 38 14 22 12 26 98
72 72
87 87
11 11
19 19
28 28
You are modifying the pointers in the pointer-array matrix_ptr within your rainGen function, so that all of them point past the end and further accesses go to "random" memory locations, which is undefined behavior. Tools like valgrind can find such errors.

Modifing Arrays without using <algorithm> functions in C++? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
So first, we start with an array of 50. The range of the values within the array can be 1-100, not repeating. Then we display the highest value of that random array. Then we display the lowest value in the array. Then comes the sorting, which would be easy using the standard library functions in the <algorithm> header, but since it's not allowed, we need to find another way around it. Then sort from high to low.
So, to display this easily... First we start with an array[50] with random numbers between 1-100
72 29 11 41 31 27 21 46 43 40 17 45 30 32 25 15 19 88 22 24 51 34 99 23 26 37 1 4 2 9 33 44 12 39 38 3 47 48 5 42 49 18 54 55 87 16 28 20 50 9
Now we display the highest number
99
Then the lowest
1
The we sort them
1 2 3 4 5 9 9 11 12 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 54 55 72 87 88 99
Then reverse sort them
99 88 87 72 55 54 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 12 11 9 9 5 4 3 2 1
So.. how would I go about doing this without algorithms?
The usual way to do this is by using loops.
For example, to traverse an array, printing every element, we could use a loop like:
for (int i=0; i<50; i++) {
std::cout << array[i] << std::endl;
}
All of the problems you mention, except sorting, can be done using a simple loop like the one above. You'll have to do your own bookkeeping in order to solve the problems, but it shouldn't be too difficult.
As for sorting, that's a more challenging problem. You might start with the wikipedia article to see how that is handled. You probably want to try implementing selection sort.
You can use bitset sort since the range of values of the array is limited to 1-100, and there is no repetition you can have a bitset array of 100 ints where each index specifies can be a 0 (that number isn't in the array) or a 1 (the number is in the array). For example the array [1, 5, 3] can be represented by the bitset array [1, 0, 1, 0, 1].
pseudo code:
MAX_SIZE = 100
bitset = new int[MAX_SIZE]
smallest = biggest = -1
for each value in array {
smallest = value if value < smallest
biggest = value if value > biggest
bitset[value-1] = 1
}
sorted = (i for i in 0..bitset.length - 1 if bitset[i] == 1)
reverse_sorted = (sorted[i] for i in sorted.length-1..0)
Not very professional but works
int array[50], used[50], sortedArray[50], buildSort = 1, genNum, max = 0, min = 101;
bool x;
srand(time(0));
//Array Generator
for(int i = 0; i < 50; i++){
do{
genNum = (1+rand()%100);
x = false;
for(int j =0; j < 50; j++){
if(genNum == used[j]){
x = true;
}
}
}while(x == true);
used[i] = genNum;
array[i] = genNum;
}
cout << "Numbers: ";
for(int d = 0; d < 50; d++){
cout << array[d] << " ";
}
cout << endl << endl;
//Max and Min finder
for(int m = 0; m < 50; m++){
if(array[m] > max){
max = array[m];
}
if(array[m] < min){
min = array[m];
}
}
cout << "Max is: " << max << endl;
cout << "Min is: " << min << endl << endl;
//Sorting
sortedArray[0] = min;
for(int v = min+1; v <= max; v++){
for(int r = 0; r < 50; r++){
if(array[r] == v){
sortedArray[buildSort] = array[r];
buildSort++;
}
}
}
cout << "Sorted: ";
for(int k = 0; k < 50; k++){
cout << sortedArray[k] << " ";
}
cout << endl << endl;
cout << "Reverse sorting: ";
for(int l = 49; l >=0; l--){
cout << sortedArray[l] << " ";
}
Well, I have not checked this code and I'm sure it has some errors in it, but hopefully this will at least give you some ideas and a good base to go off of:
/******************
*
* Your array should have 51 spots.
* The last element should be 0.
*
******************/
uint8_t findMax(uint8_t *arrayToSearch){
// Your array should end in a sentinel value of 0
uint8_t highest = 0;
for(; *arrayToSearch; arrayToSearch++){
highest = (*arrayToSearch > highest) ? *arrayToSearch : highest;
}
return highest;
}
uint8_t findMin(uint8_t *arrayToSearch){
// Your array should end in a sentinel value of 0
uint8_t lowest = 101;
for(; *arrayToSearch; arrayToSearch++){
lowest = (*arrayToSearch < lowest) ? *arrayToSearch : lowest;
}
return lowest;
}
void sortAscending(uint8_t *arrayToSearch){
// sort from low to high
// get count of array (According to your question, it should be 50, but we'll verify)
unsigned short count = 0;
uint8_t *countingPoint;
countingPoint = arrayToSeach; // make countingPoint point to the first element
while(*countingPoint){
count++;
countingPoint++;
}
// now we'll create a second array
uint8_t sortedArray[count];
// now let's begin sorting.
unsigned long int totalIterations = 0;
while(totalIterations < count){
uint8_t currentSmallest = 101; // value which will not ever exist.
signed long int smallestIndex = -1;
unsigned short offset = 0;
uint8_t *startOfArray;
startOfArray = arrayToSearch;
for(; *startOfArray; *startOfArray++, offset++){
if(currentSmallest > *startOfArray){
smallestIndex = offset;
currentSmallest = *startOfArray;
}
} /* end for */
sortedArray[totalIterations] = currentSmallest;
*(smallestIndex + arrayToSearch) = 101; /* set the value above 100 so it will be
skipped in the next for loop */
totalIterations++;
} /* end while */
/* now we'll the sorted values to the array to search */
int i;
for(i=0; i < count; i++){
*(i+arrayToSearch) = sortedArray[i];
}
// and we're done.
}
/*
* We can actually write sortDescending the same way and just modify
* the last loop to put them in reverse order
*/
void sortDescending(uint8_t *arrayToSearch){
// sort from low to high and then order as high to low
// get count of array (According to your question, it should be 50, but we'll verify)
unsigned short count = 0;
uint8_t *countingPoint;
countingPoint = arrayToSeach; // make countingPoint point to the first element
while(*countingPoint){
count++;
countingPoint++;
}
// now we'll create a second array
uint8_t sortedArray[count];
// now let's begin sorting.
unsigned long int totalIterations = 0;
while(totalIterations < count){
uint8_t currentSmallest = 101; // value which will not ever exist.
signed long int smallestIndex = -1;
unsigned short offset = 0;
uint8_t *startOfArray;
startOfArray = arrayToSearch;
for(; *startOfArray; *startOfArray++, offset++){
if(currentSmallest > *startOfArray){
smallestIndex = offset;
currentSmallest = *startOfArray;
}
} /* end for */
sortedArray[totalIterations] = currentSmallest;
*(smallestIndex + arrayToSearch) = 101; /* set the value above 100 so it will be
skipped in the next for loop */
totalIterations++;
} /* end while */
/* now we'll copy the values to the arrayToSearch in reverse order */
int i;
for(i=(count-1); i >= 0; i--){
*(i+arrayToSearch) = sortedArray[i];
}
// and we're done.
}
/* calling these */
int main(){
uint8_t yourArray[51];
// ... your code to populate this array
yourArray[50] = 0; // set the last spot to 0.
uint8_t highest = findMax(yourArray);
uint8_t lowest = findMin(yourArray);
// now make yourArray sorted by lowest to highest
sortAscending(yourArray);
// ... Whatever you need to do with it in ascending order.
// now make it sorted by highest to lowest
sortDescending(yourArray);
// ... Whatever you need to do with it in descending order.
return 0;
}
I'm a C-programmer so this is a rather C-style answer.
Some additional information that might be helpful can be found at:
http://www.sanfoundry.com/c-program-sort-array-ascending-order/
http://www.programmingsimplified.com/c/source-code/c-program-bubble-sort
http://en.wikipedia.org/wiki/Sorting_algorithm
The Wikipedia page (last link) might seem a little overwhelming, but there is a lot of great content on it.
I hope this will be of some help to you. Again, I'm not sure if the code I included will work properly. It's merely meant to convey the general idea.

Own RC4 algorithm giving wrong output

I've written the following implementation of the RC4 algorithm, where key is a RC4_KEY struct as given in the OpenSSL library. m_key is a QByteArray containing the set key. For this test, I have been using "teste" as key. As you can see, I have two more QByteArrays, one of them holding the original (input) data and the other one the encrypted (output) data.
void rc4SetKey() {
for (int i = 0; i < 256; ++i) {
key.data[i] = i;
}
for (int i = 0; i < 256; ++i) {
int j = (j + key.data[i] + m_key[i % m_key.length()]) % 256;
std::swap(key.data[i], key.data[j]);
}
}
void rc4Encrypt(QByteArray &in, QByteArray &out) {
out.clear();
out.resize(in.length());
for (int n = 0; n < in.length(); ++n) {
int i = (i + 1) % 256;
int j = (j + key.data[i]) % 256;
std::swap(key.data[i], key.data[j]);
int rand = key.data[(key.data[i] + key.data[j]) % 256];
out[n] = rand ^ in[n];
}
}
For testing purposes, I am using a text file with the following data (as hex):
31 32 33 34 35 36 37 38 38 39 31 30 0a
Using an online tool or the OpenSSL function, I get the following output (key: "teste"):
6a 9d ae b6 17 61 7b 71 5f f7 46 f0 ab
Using my own implementation, however, I get the following:
52 ec c2 b1 3d ca 6b 55 50 54 30 e7 ed
I have spent quite some time now and looked at various pseudo codes or implementations, but I am still not able to figure out where I went wrong.
This expression (in both the set-key and encrypt functions) is illegal (compiling with all warnings turned on should have pointed it out):
int j = (j + ...
In addition to being nonsense (trying to reference the value of a variable in its initialization), it doesn't match the algorithm definition - j is supposed to be declared outside the loop and not reset on each iteration.
The following should fix the key-set function. The fix for the encrypt function will be nearly the same (it also needs i to be fixed in the same way).
int j = 0;
for (int i = 0; i < 256; ++i) {
j = (j + key.data[i] + m_key[i % m_key.length()]) % 256;
std::swap(key.data[i], key.data[j]);
}