C++ Binary Level I/O
I'm trying to read a file, break it down to bit level and then apply an encryption algorithm I've written but I'm not quite sure how to go about that.
The encryption algorithm is already written, it accepts 64-bits of input to proceed with encryption so I should break down the file into segments, each 64bit in size, which shouldn't be a problem if I have the file in binary format. However I have no clue how to get a random file into binary format( individual 1's and 0's). c++ file streaming seems more concerned with the content of the file rather than the file itself. I want to break down any file to 1's & 0's regardless of file content or type.
Any ideas how to go about that ?
I was dabbling in some encryption stuff myself and had some problems reading in files properly (though my problem wasn't with getting the binary data). Anyway, take a look at these snippets. This does a simple reversible XOR encryption, but you can see how it uses std::transform() and file streams (in binary mode) to read/write binary data to the files I'm encrypting.
The main() function just runs a little driver program, but you can see how it opens the streams. You can see how XOREncryptor uses std::transform() to handle the data. Hope this helps. Cheers.
Edit: Sorry for any confusing variable names. I went back and changed 'em. Also, I open fin and fout for both reading and writing for testing purposed (so I could easily swap the outputs and inputs). An ifstream and ofstream would do fine as well, but I'm sure you knew that. :-)
...typedef char Byte;typedef long KeyType;...#pragma once#include "Encryptor.h"#include <iostream>#include <algorithm>class XOREncryptor : public Encryptor{public: XOREncryptor(KeyType Key): mKey(Key), mPass(0) {} virtual ~XOREncryptor() {} virtual Byte operator()(const Byte& b) { mPass %= sizeof(KeyType); return b ^ reinterpret_cast<Byte*>(&mKey)[mPass++]; } virtual bool encrypt(std::istream& In, std::ostream& Out) { if (!In) return false; if (!Out) return false; In.seekg(In.beg); Out.seekp(Out.beg); std::transform(std::istreambuf_iterator<Byte>(In), std::istreambuf_iterator<Byte>(), std::ostreambuf_iterator<Byte>(Out), *this); return true; } virtual KeyType getKey() const { return mKey; }private: KeyType mKey; // Key. unsigned short mPass; // Pass.};
#include <iostream>#include <fstream>#include <string>#include "XOREncryptor.h"using std::cout;using std::cin;using std::endl;using std::string;using std::ifstream;using std::ofstream;using std::fstream;using std::ios;int main(int NumArgs, char** Args){ string inFileName, outFileName; KeyType key = 1; cout << "Input: "; cin >> inFileName; cout << "Output: "; cin >> outFileName; cout << "Key: "; cin >> key; if (cin.fail()) key = 1; Encryptor* e = new XOREncryptor(key); fstream fin(inFileName.c_str(), ios::in | ios::out | ios::binary); fstream fout(outFileName.c_str(), ios::in | ios::out | ios::binary); e->encrypt(fin, fout); delete e; return 0;}
The main() function just runs a little driver program, but you can see how it opens the streams. You can see how XOREncryptor uses std::transform() to handle the data. Hope this helps. Cheers.
Edit: Sorry for any confusing variable names. I went back and changed 'em. Also, I open fin and fout for both reading and writing for testing purposed (so I could easily swap the outputs and inputs). An ifstream and ofstream would do fine as well, but I'm sure you knew that. :-)
I imagine you should just read the file as any normal file, but make sure it's in binary mode (ios::binary if you're using ifstream). Then each character you read in is just a byte of data that can be converted to an equivalent 8 bit binary value.
There might already be a function to convert a char into an 8bit binary string, but if not it shouldn't be too hard to write yourself using some bitwise operators. Then you could either save the string of '1's and '0's to another file, or plug the data straight into your encryption algorithm.
There might already be a function to convert a char into an 8bit binary string, but if not it shouldn't be too hard to write yourself using some bitwise operators. Then you could either save the string of '1's and '0's to another file, or plug the data straight into your encryption algorithm.
I still prefer this:
FILE *pFile = fopen("file.ext", "rb");
.
.
(use fread/fgetc/fseek/etc.)
.
.
fclose(pFile);
Very readable and easy to understand.
FILE *pFile = fopen("file.ext", "rb");
.
.
(use fread/fgetc/fseek/etc.)
.
.
fclose(pFile);
Very readable and easy to understand.
You should be using ifstream's read function, rather than the streaming operators, so as to bypass formatting. Also be sure to have opened the file using ios::binary.
C++ provides no mechanism to directly access bits of data. The usual procedure is to maintain an array or buffer of chars, using the bit-shifting operators to do your jiggerypokery.
Admiral
C++ provides no mechanism to directly access bits of data. The usual procedure is to maintain an array or buffer of chars, using the bit-shifting operators to do your jiggerypokery.
Admiral
It sounds like you want a long string of the *characters* '1' and '0'. You don't need that.
Your data *is* in binary format when you have a chunk of chars. There's no need to rewrite it to consist only of the ascii values for '0' and '1'.
A char is a byte is 8 bit.
If you need 64 bit of input data, you take 8 bytes. (or two ints)
If you gave it a text string containing 64 1's and 0's, that would be 512 byte of data.
Your data *is* in binary format when you have a chunk of chars. There's no need to rewrite it to consist only of the ascii values for '0' and '1'.
A char is a byte is 8 bit.
If you need 64 bit of input data, you take 8 bytes. (or two ints)
If you gave it a text string containing 64 1's and 0's, that would be 512 byte of data.
Quote:Original post by Spoonbender
It sounds like you want a long string of the *characters* '1' and '0'. You don't need that.
Actually I kinda do, the algorithm was part of a college assignment so it was supposed to be written to print out its operation in ascii characters.
I think I got a clear picture of how to take the input now, but I'm still lost as to how to translate that into ascii "binary" characters now and how to translate it back for file output.
So the data is stored in binary format, but how can I access that and get 1's and 0's.
You could AND each byte of data with different powers of two to test for the bits, but this could be slow (though I'm sure you don't need things to be all too efficient for an assignment).
Something like this, perhaps? (I'm not sure just using 1, 2, 4, 8, etc. will work; you may need to enter the hex codes, i.e., 0x01.)
Hope this helps. Someone correct me if I did something wrong. :-)
...typedef char Byte;Byte inputByte = getNextInputByte();if (Byte & 1){ // Byte has a '1' in the first place.}else{ // Byte has a '0' in the first place.}...
Something like this, perhaps? (I'm not sure just using 1, 2, 4, 8, etc. will work; you may need to enter the hex codes, i.e., 0x01.)
Hope this helps. Someone correct me if I did something wrong. :-)
You have to do some bit twiddling, here's some quick and dirty code:
This uses the bitshift operator to change the value of the 'bit' variable each loop iteration. It then AND's this value with the 'data' variable, and depending on the result, adds a '1' or '0' to the output string. This converts your byte of character information ('data') into an 8 byte string of 1's and 0's. Also check this wikipedia page for some useful info.
Hope that was what you were looking for.
unsigned char data = 20;string binaryString = "";// loop through all eight bitsfor(int i = 0; i < 8; ++i){ // shift the bit to the left unsigned char bit = (1 << (7 - i)); // add correct character to the string if((bit & data) == bit) binaryString += '1'; else binaryString += '0';}
This uses the bitshift operator to change the value of the 'bit' variable each loop iteration. It then AND's this value with the 'data' variable, and depending on the result, adds a '1' or '0' to the output string. This converts your byte of character information ('data') into an 8 byte string of 1's and 0's. Also check this wikipedia page for some useful info.
Hope that was what you were looking for.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement