tags:

views:

793

answers:

9

Hello I have a chunk of memory (allocated with malloc()) that contains bits (bit literal), I'd like to read it as an array of char, or, better, I'd like to printout the ASCII value of 8 consecutively bits of the memory.

I have allocated he memory as char *, but I've not been able to take characters out in a better way than evaluating each bit, adding the value to a char and shifting left the value of the char, in a loop, but I was looking for a faster solution. Thank you

What I've wrote for now is this:

for allocation:

char * bits = (char*) malloc(1);

for writing to mem:

ifstream cleartext;
cleartext.open(sometext);
while(cleartext.good())
{
     c = cleartext.get();
     for(int j = 0; j < 8; j++)
     {  //set(index) and reset(index) set or reset the bit at bits[i]
        (c & 0x80) ? (set(index)):(reset(index));//(*ptr++ = '1'):(*ptr++='0');
         c = c << 1;
     }..
}..

and until now I've not been able to get character back, I only get the bits printed out using:

printf("%s\n" bits);

An example of what I'm trying to do is:

input.txt contains the string "AAAB"

My program would have to write "AAAB" as "01000001010000010100000101000010" to memory (it's the ASCII values in bit of AAAB that are 65656566 in bits)

Then I would like that it have a function to rewrite the content of the memory to a file.

So if memory contains again "01000001010000010100000101000010" it would write to the output file "AAAB".

A: 

Something like this?

char *buffer = (char*)malloc(42);
// ... put something into the buffer ...
printf("%c\n", buffer[0]);

But, since you're using C++, I wonder why you bother with malloc and such...

Thomas
what other ways do you suggest me? I need to store a textfile as bits in memory for use in cryptographic functions, and once i've encrypted, i would like to reprint the resultant chars, malloc was the first and fastest thig that i thought of, but i'm open to better alternatives...
luiss
std::vector<bool> allows you to access individual bits and packs them efficiently in memory. std::bitset might be a better option, if you are using a fixed block size.
Thomas
I don't think sizes are fixed, at least for now, I'm starting the project so don't really know how it will evolve :D
luiss
Well, a better approach is new char[size] instead of malloc.
Ismael
I may misremember, but std::vector<bool> is no more efficient than std::vector<char>. Both use 1 byte per element. Consider std::vector<bitset> instead.
Alex Reynolds
so what's best? std::vector<bitset> or new char[]?because now the new char[] option is working good, does it wastes memory or does it write subsequent character in different memory places?
luiss
A: 
char* ptr = pAddressOfMemoryToRead;

while(ptr < pAddressOfMemoryToRead + blockLength)
{
     char tmp = *ptr;
     // temp now has the char from this spot in memory
     ptr++;
}
theycallmemorty
A: 

Is this what you are trying to achieve:

char* p = (char*)malloc(10 * sizeof(char));
char* p1 = p;
memcpy(p,"abcdefghij", 10);

for(int i = 0; i < 10; ++i)
{
 char c = *p1;
 cout<<c<<" ";
 ++p1;
}
cout<<"\n";
free(p);
Naveen
A: 

Can you please explain in more detail, perhaps including code? What you're saying makes no sense unless I'm completely misreading your question. Are you doing something like this?

char * chunk = (char *)malloc(256);

If so, you can access any character's worth of data by treating chunk as an array: chunk[5] gives you the 5th element, etc. Of course, these will be characters, which may be what you want, but I can't quite tell from your question... for instance, if chunk[5] is 65, when you print it like cout << chunk[5];, you'll get a letter 'A'.

However, you may be asking how to print out the actual number 65, in which case you want to do cout << int(chunk[5]);. Casting to int will make it print as an integer value instead of as a character. If you clarify your question, either I or someone else can help you further.

rmeador
and yes, as others have mentioned, why are you using malloc() in a C++ program? You should use "new". The first line of my example would read: char * chunk = new char[256]; in C++.
rmeador
A: 

Are you asking how to copy the memory bytes of an arbitrary struct into a char* array? If so this should do the trick

SomeType t = GetSomeType();
char* ptr = malloc(sizeof(SomeType));
if ( !ptr ) {
  // Handle no memory.  Probably should just crash
}
memcpy(ptr,&t,sizeof(SomeType));
JaredPar
+1  A: 
int numBytes = 512;
char *pChar = (char *)malloc(numBytes);
for( int i = 0; i < numBytes; i++ ){
   pChar[i] = '8';
}

Since this is C++, you can also use "new":

int numBytes = 512;
char *pChar = new char[numBytes];
for( int i = 0; i < numBytes; i++ ){
   pChar[i] = '8';
}
Colin
If I ever need a resize is the "new" better than "realloc"? Or would I have to copy the written bytes?
luiss
If you need to resize after allocating with "new", you would have to copy the written bytes. In that case, using C-style malloc/realloc/free could potentially be more efficient.
Colin
+1  A: 

If you want to visit every bit in the memory chunk, it looks like you need std::bitset.

char* pChunk = malloc( n );
// read in pChunk data

// iterate over all the bits.
for( int i = 0; i != n; ++i ){
    std::bitset<8>& bits = *reinterpret_cast< std::bitset<8>* >( pByte );
    for( int iBit = 0; iBit != 8; ++iBit ) {
        std::cout << bits[i];
    }
}
xtofl
+1  A: 

I'd like to printout the ASCII value of 8 consecutively bits of the memory.

The possible value for any bit is either 0 or 1. You probably want at least a byte.

char * bits = (char*) malloc(1);

Allocates 1 byte on the heap. A much more efficient and hassle-free thing would have been to create an object on the stack i.e.:

char bits; // a single character, has CHAR_BIT bits

ifstream cleartext;

cleartext.open(sometext);

The above doesn't write anything to mem. It tries to open a file in input mode.

It has ascii characters and common eof or \n, or things like this, the input would only be a textfile, so I think it should only contain ASCII characters, correct me if I'm wrong.

If your file only has ASCII data you don't have to worry. All you need to do is read in the file contents and write it out. The compiler manages how the data will be stored (i.e. which encoding to use for your characters and how to represent them in binary, the endianness of the system etc). The easiest way to read/write files will be:

// include these on as-needed basis
#include <algorithm>
#include <iostream>
#include <iterator>
#include <fstream>

using namespace std;
// ...

/* read from standard input and write to standard output */
copy((istream_iterator<char>(cin)), (istream_iterator<char>()),
                  (ostream_iterator<char>(cout)));
/*-------------------------------------------------------------*/

/* read from standard input and write to text file */
copy(istream_iterator<char>(cin), istream_iterator<char>(),
         ostream_iterator<char>(ofstream("output.txt"), "\n") );
/*-------------------------------------------------------------*/

/* read from text file and write to text file */
copy(istream_iterator<char>(ifstream("input.txt")), istream_iterator<char>(),
         ostream_iterator<char>(ofstream("output.txt"), "\n") );
/*-------------------------------------------------------------*/

The last remaining question is: Do you want to do something with the binary representation? If not, forget about it. Else, update your question one more time.

E.g: Processing the character array to encrypt it using a block cipher

/* a hash calculator */
struct hash_sha1 {
 unsigned char operator()(unsigned char x) {
    // process
    return rc;
  }
};

/* store house of characters, could've been a vector as well */
basic_string<unsigned char> line;

/* read from text file and write to a string of unsigned chars */   
copy(istream_iterator<unsigned char>(ifstream("input.txt")),
                                     istream_iterator<char>(),
                                      back_inserter(line) );

/* Calculate a SHA-1 hash of the input */   
basic_string<unsigned char> hashmsg;
transform(line.begin(), line.end(), back_inserter(hashmsg), hash_sha1());
dirkgently
the writing to mem step are the loop after that you have quoted(i.e. set(index) and reset(index) writes to the memory, they are function that I didn't copyed here, sorry)
luiss
Can the input.txt file contain anything other than ASCII/printable characters?
dirkgently
It has ascii characters and common eof or \n, or things like this, the input would only be a textfile, so I think it should only contain ASCII characters, correct me if I'm wrong
luiss
I'm sorry I thought I've yet wrote about it, yes I need the binary representation to exercise with some cryptographic function, this is why I need the translation from text to bit and viceversa, thank you
luiss
Simply pass on the char array to your cryptographic function. I'd use unsigned character to read though.
dirkgently
A: 

I'm not sure I entirely grok what you're trying to do, but a couple of suggestions:

1) use std::vector instead of malloc/free and new/delete. It's safer and doesn't have much overhead.

2) when processing, try doing chunks rather than bytes. Even though streams are buffered, it's usually more efficient grabbing a chunk at a time.

3) there's a lot of different ways to output bits, but again you don't want a stream output for each character. You might want to try something like the following:

void outputbits(char *dest, char source)
{
    dest[8] = 0;
    for(int i=0; i<8; ++i)
     dest[i] = source & (1<<(7-i)) ? '1':'0';
}

Pass it a char[9] output buffer and a char input, and you get a printable bitstring back. Decent compilers produce OK output code for this... how much speed do you need?

snemarch
I really don't need such a speed at this step, because i hope the file to encrypt/decrypt won't be so large...
luiss
What's the point of the to/from binary step, by the way?
snemarch
I need the binary representation to be able to do math operations on the bits
luiss
That sounds like a very wrong way to handle the problem - you really don't need an ascii representation of the bits to do math on them :)
snemarch
No, I need the bits of the representation to do the maths, but need theyr ascii representation to rpintout the evaluation of the "encrypted" text. Am I wrong?
luiss
Well, if you *need* to print it in binary, sure. Personally, I'd either print hexadecimal representation (or BASE64), or simply deal with raw byte values (which isn't printable, though).
snemarch