The code below shown is in visual c++
array<Byte>^ b = gcnew array <Byte> (filesize);
fs->Read(b,0,b->Length);
unsigned char *pb;
pb=(byte*)malloc(b->Length); //pb is unmanaged here.
for(int i=0;i<b->Length;i++)
{
*(pb+i)=InverseByte(b+i);
}
I want to call the function below to reverse each byte. How can I do this?
I want to do inverse of each byte of managed array b, and put it in the unmanaged array b.
unsigned char InverseByte(unsigned char* PbByte)
{
//something;
}
Fix the declaration of InverseByte:
unsigned char InverseByte(unsigned char value)
So you can then use it like this:
for (int i=0; i < b->Length; i++)
{
pb[i] = InverseByte(b[i]);
}
You mean bitwise negation I presume.
unsigned char InverseByte(unsigned char c)
{
return ~c;
}
Note that I changed the parameter to pass by value rather than passing a pointer to the value.
I also fail to see why you are using pointer arithmetic instead of indexing. That just makes your code harder to read. The loop should be written like this:
for(int i=0;i<b->Length;i++)
{
pb[i] = InverseByte(b[i]);
}
unsigned char InverseByte(unsigned char c)
{
return (c>>7)|((c&64)>>5)|((c&32)>>3)|((c&16)>>1)|((c&8)<<1)|((c&4)<<3)|((c&2)<<5)|((c&1)<<7);
}
From the comments it's clear you are reversing the bytes (i.e. reordering them front-to-back) rather than inverting (i.e. subtracting a variable from its maximum value) or negating (i.e. flipping 1's and 0's), so should name the function accordingly.
Here's a neat little snippet from Seander's bithacks:
unsigned int v; // input bits to be reversed
unsigned int r = v; // r will be reversed bits of v; first get LSB of v
int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end
for (v >>= 1; v; v >>= 1)
{
r <<= 1;
r |= v & 1;
s--;
}
r <<= s; // shift when v's highest bits are zero
return r;
If you combine Hans Passant's answer with this, you should have all the pieces to put together your function.
Related
I'm looking to convert a byte array of LSB,MSB to an array of int
Currently, I'm using a for loop and converting each set of values individually,
void ConvertToInt(int OutArray[], byte InArray[], int InSize)
{
for(int i=0; InSize/2>=i; i++)
{
int value = InArray[2*i] + (InArray[2*i+1] << 8);
OutArray[i]=value;
}
}
However, given that:
OutArray[] is created in the parent function for this specific purpose.
I don't need InArray[] after this operation
Is there a more efficient way to directly convert my byte array to an Int array?
Operate on the array as bytes, then assemble and place into integers:
void ConvertToInt(int OutArray[], byte InArray[], int InSize)
{
int * p_output = &OutArray[0];
for (size_t i = 0; i < inSize; ++i)
{
byte lsb = InArray[i++];
byte msb = InArray[i];
int value = (msb << 8) | lsb;
*p_output++ = value;
}
}
You may need to convert to larger integers, depending on the warning level:
for (size_t i = 0U; i < InSize; i += 2U)
{
const byte lsb = InArray[i + 0U];
const byte msb = InArray[i + 1U];
const int lsb_as_int(static_cast<int>(lsb));
const int msb_as_int(static_cast<int>(msb));
*p_output++ = (msb_as_int * 256) + lsb_as_int;
}
In the above code, the promotion of byte to int is explicit. The variables are temporary and the compiler should simplify this (so don't worry about the temporary variables). Also, the temporary variables allow you to see the intermediate values when using a debugger.
Print out the assembly language generated by the compiler, in both debug and release (optimized) versions, before optimizing or panicking. A good compiler should optimize the loop contents to a few instructions.
If your machine is little endian, then this can be done in O(1) time and additional-memory complexity.
int16_t *ToInt(byte inArray[])
{
return reinterpret_cast<int16_t*>(inArray);
}
If you either want it in a new array, or your machine is big endian, you must walk over all elements. In that case the best you can get is O(n) time complexity.
The only way to get around that, is to wrap the original array in an accessor class that will convert between byte pairs to int. Such a wrapper will speed the time for the first several accesses, but if at some point all the array has to be read, then the lazy evaluation will cost more than converting the array from the beginning.
On the positive sude, the wrapper costs only O(1) additional memory. Also, if you want to save the array as bytes, you don't have to convert.
class as_int {
public:
class proxy
{
public:
proxy & operator=(int16_t value)
{
pair_[0] = value& 255;
pair_[1] = ((unsigned)value >> 8) & 255;
return *this;
}
operator int16_t() ......
private:
proxy(byte*pair): pair_(pair) {}
friend class as_int;
};
as_int(byte *arr, unsigned num_bytes)
: arr_(arr), size_(num_bytes/2)
{}
int16_t operator[] const (unsigned i)
{
assert(i < size);
byte *pair = arr_ + (i*2);
return pair[0] + (pair[1]<<8);
}
proxy operator[] (unsigned i)
{
assert(i < size);
return proxy(arr_ + (i*2));
}
....
And the use is quite trivial:
as_int arr(InByteArray, InSize);
std::cout << arr[3] << '\n';
arr[5] = 30000;
arr[3] = arr[6] = 500;
How can I convert an unsigned char array that contains letters into an integer. I have tried this so for but it only converts up to four bytes. I also need a way to convert the integer back into the unsigned char array .
int buffToInteger(char * buffer)
{
int a = static_cast<int>(static_cast<unsigned char>(buffer[0]) << 24 |
static_cast<unsigned char>(buffer[1]) << 16 |
static_cast<unsigned char>(buffer[2]) << 8 |
static_cast<unsigned char>(buffer[3]));
return a;
}
It looks like you're trying to use a for loop, i.e. repeating a task over and over again, for an in-determinant amount of steps.
unsigned int buffToInteger(char * buffer, unsigned int size)
{
// assert(size <= sizeof(int));
unsigned int ret = 0;
int shift = 0;
for( int i = size - 1; i >= 0, i-- ) {
ret |= static_cast<unsigned int>(buffer[i]) << shift;
shift += 8;
}
return ret;
}
What I think you are going for is called a hash -- converting an object to a unique integer. The problem is a hash IS NOT REVERSIBLE. This hash will produce different results for hash("WXYZABCD", 8) and hash("ABCD", 4). The answer by #Nicholas Pipitone DOES NOT produce different outputs for these different inputs.
Once you compute this hash, there is no way to get the original string back. If you want to keep knowledge of the original string, you MUST keep the original string as a variable.
int hash(char* buffer, size_t size) {
int res = 0;
for (size_t i = 0; i < size; ++i) {
res += buffer[i];
res *= 31;
}
return res;
}
Here's how to convert the first sizeof(int) bytes of the char array to an int:
int val = *(unsigned int *)buffer;
and to convert in back:
*(unsigned int *)buffer = val;
Note that your buffer must be at least the length of your int type size. You should check for this.
I have a base64 string containing bits, I have alredy decoded it with the code in here. But I'm unable to transform the resultant string in bits I could work with. Is there a way to convert the bytes contained in the code to a vector of bools containing the bits of the string?
I have tried converting the char with this code but it failed to conver to a proper char
void DecodedStringToBit(std::string const& decodedString, std::vector<bool> &bits) {
int it = 0;
for (int i = 0; i < decodedString.size(); ++i) {
unsigned char c = decodedString[i];
for (unsigned char j = 128; j > 0; j <<= 1) {
if (c&j) bits[++it] = true;
else bits[++it] = false;
}
}
}
Your inner for loop is botched: it's shifting j the wrong way. And honestly, if you want to work with 8-bit values, you should use the proper <stdint.h> types instead of unsigned char:
for (uint8_t j = 128; j; j >>= 1)
bits.push_back(c & j);
Also, remember to call bits.reserve(decodedString.size() * 8); so your program doesn't waste a bunch of time on resizing.
I'm assuming the bit order is MSB first. If you want LSB first, the loop becomes:
for (uint8_t j = 1; j; j <<= 1)
In OP's code, it is not clear if the vector bits is of sufficient size, for example, if it is resized by the caller (It should not be!). If not, then the vector does not have space allocated, and hence bits[++it] may not work; the appropriate thing might be to push_back. (Moreover, I think the code might need the post-increment of it, i.e. bits[it++] to start from bits[0].)
Furthermore, in OP's code, the purpose of unsigned char j = 128 and j <<= 1 is not clear. Wouldn't j be all zeros after the first iteration? If so, the inner loop would always run for only one iteration.
I would try something like this (not compiled):
void DecodedStringToBit(std::string const& decodedString,
std::vector<bool>& bits) {
for (auto charIndex = 0; charIndex != decodedString.size(); ++charIndex) {
const unsigned char c = decodedString[charIndex];
for (int bitIndex = 0; bitIndex != CHAR_BIT; ++bitIndex) {
// CHAR_BIT = bits in a char = 8
const bool bit = c & (1 << bitIndex); // bitwise-AND with mask
bits.push_back(bit);
}
}
}
i know there is a lot of questions about it, but most of them uses fixed sized converters, like 4 bytes to int and etc.
I have an templated functions to convert bytes to numbers and etc, but have a problem :D
template <typename IntegerType>
static IntegerType bitsToInt(BYTE* bits, bool little_endian = true)
{
IntegerType result = 0;
if (little_endian)
for (int n = sizeof(IntegerType); n >= 0; n--)
result = (result << 8) + bits[n];
else
for (int n = 0; n < sizeof(IntegerType); n++)
result = (result << 8) + bits[n];
return result;
}
template <typename IntegerType>
static BYTE *intToBits(IntegerType value)
{
BYTE result[sizeof(IntegerType)] = { 0 };
for (int i = 0; i < sizeof(IntegerType); i++)
result = (value >> (i * 8));
return result;
}
static void TestConverters()
{
short int test = 12345;
BYTE *bytes = intToBits<short int>(test);
short int test2 = bitsToInt<short int>(bytes); //<--i getting here different number, then 12345, so something goes wrong at conversion
}
So, could anyone say what's wrong here?
static BYTE *intToBits(IntegerType value)
This is returning a pointer to locally allocated memory, which once the function returns goes out of scope and is no longer valid.
There are several bugs in the function intsToBits
1. Insted of
result = (value >> (i * 8));
there should be
result[i] = 0xFF & (value >> (i * 8));
More serious one you return the pointer to the memory on the stack, which is generally incorrect after you exit the function. You shoul allocate the memory with the new operator.
BYTE * result = new BYTE[sizeof(IntegerType)];
The you'll be needed to release the memory
This may not be your only problem, but intToBits is returning a pointer to a local variable, which is undefined behavior.
Try using new to allocate the byte array you return
I want to store a 4-byte int in a char array... such that the first 4 locations of the char array are the 4 bytes of the int.
Then, I want to pull the int back out of the array...
Also, bonus points if someone can give me code for doing this in a loop... IE writing like 8 ints into a 32 byte array.
int har = 0x01010101;
char a[4];
int har2;
// write har into char such that:
// a[0] == 0x01, a[1] == 0x01, a[2] == 0x01, a[3] == 0x01 etc.....
// then, pull the bytes out of the array such that:
// har2 == har
Thanks guys!
EDIT: Assume int are 4 bytes...
EDIT2: Please don't care about endianness... I will be worrying about endianness. I just want different ways to acheive the above in C/C++. Thanks
EDIT3: If you can't tell, I'm trying to write a serialization class on the low level... so I'm looking for different strategies to serialize some common data types.
Unless you care about byte order and such, memcpy will do the trick:
memcpy(a, &har, sizeof(har));
...
memcpy(&har2, a, sizeof(har2));
Of course, there's no guarantee that sizeof(int)==4 on any particular implementation (and there are real-world implementations for which this is in fact false).
Writing a loop should be trivial from here.
Not the most optimal way, but is endian safe.
int har = 0x01010101;
char a[4];
a[0] = har & 0xff;
a[1] = (har>>8) & 0xff;
a[2] = (har>>16) & 0xff;
a[3] = (har>>24) & 0xff;
#include <stdio.h>
int main(void) {
char a[sizeof(int)];
*((int *) a) = 0x01010101;
printf("%d\n", *((int *) a));
return 0;
}
Keep in mind:
A pointer to an object or incomplete type may be converted to a pointer to a different
object or incomplete type. If the resulting pointer is not correctly aligned for the
pointed-to type, the behavior is undefined.
Note: Accessing a union through an element that wasn't the last one assigned to is undefined behavior.
(assuming a platform where characters are 8bits and ints are 4 bytes)
A bit mask of 0xFF will mask off one character so
char arr[4];
int a = 5;
arr[3] = a & 0xff;
arr[2] = (a & 0xff00) >>8;
arr[1] = (a & 0xff0000) >>16;
arr[0] = (a & 0xff000000)>>24;
would make arr[0] hold the most significant byte and arr[3] hold the least.
edit:Just so you understand the trick & is bit wise 'and' where as && is logical 'and'.
Thanks to the comments about the forgotten shift.
int main() {
typedef union foo {
int x;
char a[4];
} foo;
foo p;
p.x = 0x01010101;
printf("%x ", p.a[0]);
printf("%x ", p.a[1]);
printf("%x ", p.a[2]);
printf("%x ", p.a[3]);
return 0;
}
Bear in mind that the a[0] holds the LSB and a[3] holds the MSB, on a little endian machine.
Don't use unions, Pavel clarifies:
It's U.B., because C++ prohibits
accessing any union member other than
the last one that was written to. In
particular, the compiler is free to
optimize away the assignment to int
member out completely with the code
above, since its value is not
subsequently used (it only sees the
subsequent read for the char[4]
member, and has no obligation to
provide any meaningful value there).
In practice, g++ in particular is
known for pulling such tricks, so this
isn't just theory. On the other hand,
using static_cast<void*> followed by
static_cast<char*> is guaranteed to
work.
– Pavel Minaev
You can also use placement new for this:
void foo (int i) {
char * c = new (&i) char[sizeof(i)];
}
#include <stdint.h>
int main(int argc, char* argv[]) {
/* 8 ints in a loop */
int i;
int* intPtr
int intArr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
char* charArr = malloc(32);
for (i = 0; i < 8; i++) {
intPtr = (int*) &(charArr[i * 4]);
/* ^ ^ ^ ^ */
/* point at | | | */
/* cast as int* | | */
/* Address of | */
/* Location in char array */
*intPtr = intArr[i]; /* write int at location pointed to */
}
/* Read ints out */
for (i = 0; i < 8; i++) {
intPtr = (int*) &(charArr[i * 4]);
intArr[i] = *intPtr;
}
char* myArr = malloc(13);
int myInt;
uint8_t* p8; /* unsigned 8-bit integer */
uint16_t* p16; /* unsigned 16-bit integer */
uint32_t* p32; /* unsigned 32-bit integer */
/* Using sizes other than 4-byte ints, */
/* set all bits in myArr to 1 */
p8 = (uint8_t*) &(myArr[0]);
p16 = (uint16_t*) &(myArr[1]);
p32 = (uint32_t*) &(myArr[5]);
*p8 = 255;
*p16 = 65535;
*p32 = 4294967295;
/* Get the values back out */
p16 = (uint16_t*) &(myArr[1]);
uint16_t my16 = *p16;
/* Put the 16 bit int into a regular int */
myInt = (int) my16;
}
char a[10];
int i=9;
a=boost::lexical_cast<char>(i)
found this is the best way to convert char into int and vice-versa.
alternative to boost::lexical_cast is sprintf.
char temp[5];
temp[0]="h"
temp[1]="e"
temp[2]="l"
temp[3]="l"
temp[5]='\0'
sprintf(temp+4,%d",9)
cout<<temp;
output would be :hell9
union value {
int i;
char bytes[sizof(int)];
};
value v;
v.i = 2;
char* bytes = v.bytes;