I'm trying to create a program to hide data in a image file. Data bits are hidden into last bit of every pixels blue value. First four pixels contain the length of following data bytes.
Everything works fine when I encrypt the data to image and then decrypt it without saving the image in between. However if I encrypt the data to an image and then save it and then open the file again and try to decrypt it, decryption fails since the values seem to have changed.
I wonder if there is something similar happening as with txt files where there is BOM containing byte order data prepended into the file?
The code works if I change the color c = crypted.pixels[pos + i];
to color c = original.pixels[pos + i]; in readByteAt function
and run the encrypting function first and then the decryption function.
This causes the code to run the decryption function on the just encrypted image still in program memory instead reading it from the file.
Any ideas on what causes this or how to prevent it are welcome!
here is the full (messy) code:
PImage original;
PImage crypted;
int imagesize;
boolean ready = false;
void setup() {
size(100, 100);
imagesize = width * height;
}
void draw() {
}
void encrypt()
{
original = loadImage("image.jpg");
original.loadPixels();
println("begin encrypt");
int pos = 0;
byte b[] = loadBytes("DATA.txt");
println("encrypting in image...");
int len = b.length;
println("len " + len);
writeByteAt((len >> (3*8)) & 0xFF, 0);
writeByteAt((len >> (2*8)) & 0xFF, 8);
writeByteAt((len >> (1*8)) & 0xFF, 16);
writeByteAt(len & 0xFF, 24);
pos = 32;
for (int i = 3; i < b.length; i++) {
int a = b[i] & 0xff;
print(char(a));
writeByteAt(a, pos);
pos += 8;
}
original.updatePixels();
println();
println("done");
original.save("encrypted.jpg");
}
void writeByteAt(int b, int pos)
{
println("writing " + b + " at " + pos);
for (int i = 0; i < 8; i++)
{
color c = original.pixels[pos + i];
int v = int(blue(c));
if ((b & (1 << i)) > 0)
{
v = v | 1;
} else
{
v = v & 0xFE;
}
original.pixels[pos+i] = color(red(c), green(c), v);
//original.pixels[pos+i] = color(255,255,255);
}
}
int readByteAt(int pos)
{
int b = 0;
for (int i = 0; i < 8; i++)
{
color c = crypted.pixels[pos + i];
int v = int(blue(c));
if ((v & 1) > 0)
{
b += (1 << i);
}
}
return b;
}
void decrypt()
{
crypted = loadImage("encrypted.jpg");
crypted.loadPixels();
println("begin decrypt");
int pos = 0;
PrintWriter output = createWriter("out.txt");
println("decrypting...");
int len = 0;
len += readByteAt(0) << 3*8;
len += readByteAt(8) << 2*8;
len += readByteAt(16) << 1*8;
len += readByteAt(24);
pos = 32;
if(len >= imagesize)
{
println("ERROR: DATA LENGTH OVER IMAGE SIZE");
return;
}
println(len);
while (pos < ((len+1)*8)) {
output.print(char(readByteAt(pos)));
print(char(readByteAt(pos)));
pos += 8;
}
output.flush(); // Writes the remaining data to the file
output.close();
println("\nDone");
}
void keyPressed()
{
if(key == 'e')
{
encrypt();
}
if(key == 'd')
{
decrypt();
}
}
Related
I have this function that will split the string. After running it in a while loop of read file, the program will exit instead of continue the next step of functions.
vector <string> splitString (string str, string delim){
vector <string> result;
size_t pos = 0;
string token;
while ((pos = str.find(delim)) != std::string::npos){
token = str.substr(0, pos);
result.push_back(token);
str.erase(0, pos+delim.length());
}
if (!str.empty())
result.push_back(str);
return (result);
}
void readCityLocation(int ** cityMap){
ifstream inFile;
inFile.open(filename[0]);
string line;
while (getline(inFile, line)){
int xCoordinate;
int yCoordinate;
string xValue;
string yValue;
//Get xCoordinate...
vector <string> splitThis = splitString(line,",");
xValue = splitThis[0];
cout << line;
}
An function called option2(), will create a table and call void readCityLocation( )
void option2(){
cout << endl << endl;
int ** table = new int * [gridXEnd + 1];
for (int i = 0; i < gridXEnd + 1; i++) {
table[i] = new int[gridYEnd + 1];
}
//Initialize all the array value in table to be 0
for (int i = 0; i < gridXEnd + 1; i++) {
for (int j = 0; j < gridYEnd + 1; j++) {
table[i][j] = 0;
//To be remove: Error Handling
//cout << table[i][j] << " Grid X: " << i << " Grid Y: " << j << endl;
}
}
readCityLocation(table);
}
I am fairly new to all this and can't figure out whats the problem. Any assistance is appreciated. Thank you.
I'm having some trouble with multiplying an array (char array in this particular case) by a value.
My code looks like this:
char* tab1 = copy("11");
char t = '2';
int length = strlen(tab1) + 2;
char*result = populate('0', length);
int p_length = strlen(tab1);
for (int j = p_length - 1; j >= 0; j--) {
char* tmp = multiply_chars(tab1[j], t);
v_shove(tmp, j);
char* tmp2 = add_tables(result, tmp);
delete[] result;
result = tmp2;
delete[] tmp;
}
cout << result << endl;
delete[] result;
delete[] tab1;
None of the methods used (that's populate, multiply_chars and add_tables) causes a leak when ran in an infinite loop. I've narrowed the leak to the
char* tmp2 = add_tables(result, tmp);
delete[] result;
result = tmp2;
part, but have no idea why it would happen.
I check for leaks by running snippets in an infinite loop and checking memory usage.
Any help would be appreciated! If need be I'll post the code of the methods used, but decided not to for the sake of brevity here. They all return new cstrings. Also, the t2 variable is there from when I was checking the array by array multiplication, which also leaked - decided to do array by value multiplication first.
(Now, to be completely honest this is one of the methods required for a school project, but it's such a miniscule part of it, that I thought it wouldn't hurt if I asked - the teacher isn't really big on helping with particular code problems)
The functions are:
char * add_tables(const char * table1, const char * table2)
{
char* tmp1 = get_string_trailing("0",table1);
char* tmp2 = get_string_trailing("0", table2);
int l1 = strlen(tmp1), l2 = strlen(tmp2);
if (l1 != l2) {
if (l1 > l2) {
char* t = resize_string(tmp2, l1 - l2, '0');
delete[] tmp2;
tmp2 = t;
}
else {
char* t = resize_string(tmp1, l2 - l1, '0');
delete[] tmp1;
tmp1 = t;
}
}
int length = strlen(tmp1) + 2;
char*result = new char[length];
result[length - 1] = 0;
int buffer = 0;
for (int i = length - 2; i > 0; i--) {
int t = buffer + (tmp1[i-1]-'0') + (tmp2[i-1]-'0');
result[i] = (t% 10)+'0';
buffer = (t - (t % 10))/10;
}
result[0] = buffer + '0';
char* t = get_string_trailing("0", result);
delete[]result;
result = t;
delete[]tmp1;
delete[]tmp2;
return result;
}
void v_shove(char *&c, int i)
{
char* tmp = shove(c, i);
delete[] c;
c = tmp;
}
char * populate(const char populator, int length)
{
char* result = new char[length + 1];
result[length] = 0;
for (int i = 0; i < length; i++) {
result[i] = populator;
}
return result;
}
char * multiply_chars(const char c1,const char c2)
{
char*result = new char[3];
result[2] = 0;
char tmp1 = c1 - '0', tmp2 = c2 - '0';
result[1] = (tmp1*tmp2 % 10) + '0';
result[0] = (tmp1*tmp2 - (tmp1*tmp2 % 10)) / 10 + '0';
char* r = get_string_trailing("0", result);
delete[] result;
result = r;
return result;
}
int get_length_trailing(const char * ignore,const char * table)
{
int length = 0;
int i = 0;
bool flag = true;
while (i < strlen(table)) {
if (flag) {
for (int j = 0; j < strlen(ignore); j++)
if (table[i] == ignore[j])goto BREAKPOINT;
}
flag = false;
length++;
BREAKPOINT:i++;
}
return length;
}
char * get_string_trailing(const char * ignore,const char * table)
{
int result_length = get_length_trailing(ignore, table);
char* result = new char[result_length + 1];
int counter = 0;
int i = 0;
bool flag = true;
while (i < strlen(table)) {
if (flag)
for (int j = 0; j < strlen(ignore); j++)
if (table[i] == ignore[j])goto BREAKPOINT;
flag = false;
result[counter] = table[i];
counter++;
BREAKPOINT:i++;
}
result[result_length] = 0;
if (result_length == 0) return copy("0");
return result;
}
char * shove(const char * table1, int index)
{
char*result = "0";
int length = strlen(table1) + index + 1;
result = new char[length];
result[length - 1] = 0;
if (index > 0) {
for (int i = 0; i < strlen(table1); i++)
result[i] = table1[i];
for (int i = 0; i < index; i++)
result[strlen(table1) + i] = '0';
}
else {
for (int i = 0; i < strlen(result); i++)
result[i] = table1[i];
}
char* t = get_string_trailing("0", result);
delete[] result;
result = t;
return result;
}
There is at least a memory leak in get_string_trailing: if result_length is zero, you return a copy and do not delete result. There are also confusions between "string" (such as "0") and 'char': with double quotes, the terminating string character (\0) is automatically appended to the string, while simple quotes only define a character. So "0" is made of 2 char in memory and can not be stored in a pointer (undefined behavior, overwriting memory).
To summarize: here you are writing C, not learning C++. If you have to deal with C strings (you are writing a low-level pilot in C or your professor still doesn't understand that C and C++ are different languages), at least use the functions of the string.h (in C) / cstring (in C++) header to minimize the chance of memory leak or undefined behavior. If you do not have to use C strings, use std::string and the string manipulation tools of the standard library. Your work will be much easier, and your code much less vulnerable to bugs:
#include <string>
#include <iostream>
using namespace std;
int main()
{
string tab1("11")
string t("2") // never use the single quotes for a string
cout << stoi(tab1) * stoi(t) << endl;
return;
}
That's it!
ref void init_board (ref int side, ref char[][] board) //make empty symbol chessboard
{
const char black = ' ';
const char white = 0xB0;
board[0][0] = ' ';
for (int i = 1; i <= side; i++)
{
board[i][0] = 0x30 + i; //Setting nums; "Error: Cannot convert int to char"
board[0][i] = 0x40 + i; //Setting letters; same here
for (int j = 1; j <= side; j++)
board[i][j] = (i+j)%2 == 0 ? black : white; //making black-white board
}
}
I'm trying to make a simple symbol chessboard. How do I set nums and letters depending or number of row/column correctly? board[i][0] = 0x30 + i; (or 0x40) works in C++, but not in D.
You already have what you need in the std.conv module. - The best is to use the std.conv.to.
import std.conv;
import std.stdio;
void main() {
int i = 68;
char a = to!char(i);
writeln(a);
}
Output:
D
board[i][0] = cast(char)(0x30 + i);
Keep in mind that when converting like this, it could overflow.
I know its a bit shame, but i don't understand the compression technique in VIntWritable and VLongWritable. Can someone elaborate with an example
Code snippet from WritableUtils.java
public static void writeVLong(DataOutput stream, long i) throws IOException {
if (i >= -112 && i <= 127) {
stream.writeByte((byte)i);
return;
}
int len = -112;
if (i < 0) {
i ^= -1L; // take one's complement'
len = -120;
}
long tmp = i;
while (tmp != 0) {
tmp = tmp >> 8;
len--;
}
stream.writeByte((byte)len);
len = (len < -120) ? -(len + 120) : -(len + 112);
for (int idx = len; idx != 0; idx--) {
int shiftbits = (idx - 1) * 8;
long mask = 0xFFL << shiftbits;
stream.writeByte((byte)((i & mask) >> shiftbits));
}
}
Can we do the run-length encoding in place(assuming the input array is very large)
We can do for the cases such as AAAABBBBCCCCDDDD
A4B4C4D4
But how to do it for the case such as ABCDEFG?
where the output would be A1B1C1D1E1F1G1
My first thought was to start encoding from the end, so we will use the free space (if any), after that we can shift the encoded array to the start. A problem with this approach is that it will not work for AAAAB, because there is no free space (it's not needed for A4B1) and we will try to write AAAAB1 on the first iteration.
Below is corrected solution:
(let's assume the sequence is AAABBC)
encode all groups with two or more elements and leave the rest unchanged (this will not increase length of the array) -> A3_B2C
shift everything right eliminating empty spaces after first step -> _A3B2C
encode the array from the start (reusing the already encoded groups of course) -> A3B2C1
Every step is O(n) and as far as I can see only constant additional memory is needed.
Limitations:
Digits are not supported, but that anyway would create problems with decoding as Petar Petrov mentioned.
We need some kind of "empty" character, but this can be worked around by adding zeros: A03 instead of A3_
C++ solution O(n) time O(1) space
string runLengthEncode(string str)
{
int len = str.length();
int j=0,k=0,cnt=0;
for(int i=0;i<len;i++)
{
j=i;
cnt=1;
while(i<len-1 && str[i]==str[i+1])
{
i++;
cnt++;
}
str[k++]=str[j];
string temp =to_string(cnt);
for(auto m:temp)
str[k++] = m;
}
str.resize(k);
return str;
}
null is used to indicate which items are empty and will be ignored for encoding. Also you can't encode digits (AAA2222 => A324 => 324 times 'A', but it's A3;24). Your question opens more questions.
Here's a "solution" in C#
public static void Encode(string[] input)
{
var writeIndex = 0;
var i = 0;
while (i < input.Length)
{
var symbol = input[i];
if (symbol == null)
{
break;
}
var nextIndex = i + 1;
var offset = 0;
var count = CountSymbol(input, symbol, nextIndex) + 1;
if (count == 1)
{
ShiftRight(input, nextIndex);
offset++;
}
input[writeIndex++] = symbol;
input[writeIndex++] = count.ToString();
i += count + offset;
}
Array.Clear(input, writeIndex, input.Length - writeIndex);
}
private static void ShiftRight(string[] input, int nextIndex)
{
var count = CountSymbol(input, null, nextIndex, (a, b) => a != b);
Array.Copy(input, nextIndex, input, nextIndex + 1, count);
}
private static int CountSymbol(string[] input, string symbol, int nextIndex)
{
return CountSymbol(input, symbol, nextIndex, (a, b) => a == b);
}
private static int CountSymbol(string[] input, string symbol, int nextIndex, Func<string, string, bool> cmp)
{
var count = 0;
var i = nextIndex;
while (i < input.Length && cmp(input[i], symbol))
{
count++;
i++;
}
return count;
}
The 1st solution does not take care of single characters. For example - 'Hi!' will not work. I've used totally different approach, used 'insert()' functions to add inplace. This take care of everything, whether the total 'same' character is > 10 or >100 or = 1.
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
string name = "Hello Buddy!!";
int start = 0;
char distinct = name[0];
for(int i=1;i<name.length()+1;){
if(distinct!=name[i]){
string s = to_string(i-start);
name.insert(start+1,s);
name.erase(name.begin() + start + 1 + s.length(),name.begin() + s.length() + i);
i=start+s.length()+1;
start=i;
distinct=name[start];
continue;
}
i++;
}
cout<<name;
}
Suggest me if you find anything incorrect.
O(n), in-place RLE, I couldn't think better than this. It will not place a number, if chars occurence is just 1. Will also place a9a2, if the character comes 11 times.
void RLE(char *str) {
int len = strlen(str);
int count = 1, j = 0;
for (int i = 0; i < len; i++){
if (str[i] == str[i + 1])
count++;
else {
int times = count / 9;
int rem = count % 9;
for (int k = 0; k < times; k++) {
str[j++] = str[i];
_itoa(9, &str[j++], 10);
count = count - 9;
}
if (count > 1) {
str[j++] = str[i];
_itoa(rem, &str[j++], 10);
count = 1;
}
else
str[j++] = str[i];
}
}
cout << str;
}
I/P => aaabcdeeeefghijklaaaaa
O/P => a3bcde4fghijkla5
Inplace solution using c++ ( assumes length of encoding string is not more than actual string length):
#include <bits/stdc++.h>
#include<stdlib.h>
using namespace std;
void replacePattern(char *str)
{
int len = strlen(str);
if (len == 0)
return;
int i = 1, j = 1;
int count;
// for each character
while (str[j])
{
count = 1;
while (str[j] == str[j-1])
{
j = j + 1;
count++;
}
while(count > 0) {
int rem = count%10;
str[i++] = to_string(rem)[0];
count = count/10;
}
// copy character at current position j
// to position i and increment i and j
if (str[j])
str[i++] = str[j++];
}
// add a null character to terminate string
if(str[len-1] != str[len-2]) {
str[i] = '1';
i++;
}
str[i] = '\0';
}
// Driver code
int main()
{
char str[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabccccc";
replacePattern(str);
cout << str;
return 0;
}