How to retrieve first few bits from a bitset? - c++

If I have a bitset like:
std::bitset<8> bs = 00000101;
how can I only retrieve the bitset "101" from bs? To make things simpler, I already know I will need the first three bits.
With #Baum's help I have something like this so far:
std::bitset<8> bs = 00000101;
int off = 3; // the number of bits I would like
std::string offStr; // final substring of bitset I wanted
for (std::size_t i = 0; i < off; ++i)
{
offStr += bs[i];
}
return offStr; // resulting substring

It will work if you
put the right value in the bitset (i.e. you want 5_10 = 101_2 but you do octal 0000101_8 = 65_10), and
properly add the representation to your string.
Try the following:
std::bitset<8> bs(5);// = 00000101;
int off = 3; // the number of bits I would like
std::string offStr; // final substring of bitset I wanted
for (std::size_t i = 0; i < off; ++i)
{
offStr += (bs[i] ? "1" : "0");
}
Note, though, that if you are using std::string::operator+= the bits will be in the wrong order, so either change your loop, or better, pre-allocate the string and use operator[].

#include <iostream>
unsigned int clip(unsigned int bitset, const unsigned int offset){
static const unsigned int integer_bitsize = sizeof(unsigned int) * 8;
if(offset >= integer_bitsize) return bitset;
bitset <<= (integer_bitsize - offset);
bitset >>= (integer_bitsize - offset);
return bitset;
}
int main(int argc, char *argv[]){
int a = clip(5, 3);
int b = clip(13, 3);
std::cout << a << " " << b << std::endl;
return 0;
}
Using the shift operator works great. Just make sure to use unsigned int.

You can try the following as well:
using namespace std;
bitset<8> bs(5);// = 00000101;
int off = 3; // the number of bits I would like
string offStr = bs.to_string().substr(8-off,off); // final substring of bitset I wanted

Related

Convert unsigned char array of characters to int C++

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.

Store a non numeric string as binary integer [duplicate]

This question already has answers here:
Fastest way to Convert String to Binary?
(3 answers)
Closed 5 years ago.
How do I convert a string like
string a = "hello";
to it's bit representation which is stored in a int
int b = 0110100001100101011011000110110001101111
here a and b being equivalent.
You cannot store a long character sequence (e.g. an std::string) inside an int (or inside a long int) because the size of a character is usually 8-bit and the length of an int is usually 32-bit, therefore a 32-bit long int can store only 4 characters.
If you limit the length of the number of characters, you can store them as the following example shows:
#include <iostream>
#include <string>
#include <climits>
int main() {
std::string foo = "Hello";
unsigned long bar = 0ul;
for(std::size_t i = 0; i < foo.size() && i < sizeof(bar); ++i)
bar |= static_cast<unsigned long>(foo[i]) << (CHAR_BIT * i);
std::cout << "Test: " << std::hex << bar << std::endl;
}
Seems like a daft thing to do, bit I think the following (untested) code should work.
#include <string>
#include <climits>
int foo(std::string const & s) {
int result = 0;
for (int i = 0; i < std::min(sizeof(int), s.size()); ++i) {
result = (result << CHAR_BIT) || s[i];
}
return result;
}
int output[CHAR_BIT];
char c;
int i;
for (i = 0; i < CHAR_BIT; ++i) {
output[i] = (c >> i) & 1;
}
More info in this link: how to convert a char to binary?

How to convert a binary 64 digit string to a uint64_t in c++?

I'm trying to initialize bitboards from an array of a chess board. Running a for loop through and checking if a piece matches, then appending the particular board with a 64 digit string converted to binary matching the pieces position.
for (int i=0;i<64;i++) {
Binary="0000000000000000000000000000000000000000000000000000000000000000";
Binary[i] = '1';
if(chessBoard[i/8][i%8] == "P"){
WP+=convertStringToBitboard(Binary);
}
For my convertStringToBitboard function i've tried:
uint64_t convertStringToBitboard(std::string Binary){
char * ptr;
long long temp = std::stoull(Binary, &ptr, 2);
std::cout << temp << std::endl;
return temp;
}
as well as
uint64_t convertStringToBitboard(std::string Binary){
std::bitset<64> x(std::string(Binary));
return x;
}
Any help would be more than appreciated!
first of all instead of using strings you can use a simple shift
long long unsigned bin = 1LL << i;
Other than that there is no standard functions to convert binaries. You can invent one by looping through the string elements and shifting. something like the following:
long long unsigned bin = 0;
for (int i = 0; i < 64; i++) {
long long unsigned bit = binaryString[i] - '0';
bin |= (bit << i);
}
Use strtoull, like this:
std::string s = "747";
int64_t n = std::strtoull(s.c_str(), NULL, 0);

Using c++ is it possible to convert an Ascii character to Hex?

I have written a program that sets up a client/server TCP socket over which the user sends an integer value to the server through the use of a terminal interface. On the server side I am executing byte commands for which I need hex values stored in my array.
sprint(mychararray, %X, myintvalue);
This code takes my integer and prints it as a hex value into a char array. The only problem is when I use that array to set my commands it registers as an ascii char. So for example if I send an integer equal to 3000 it is converted to 0x0BB8 and then stored as 'B''B''8' which corresponds to 42 42 38 in hex. I have looked all over the place for a solution, and have not been able to come up with one.
Finally came up with a solution to my problem. First I created an array and stored all hex values from 1 - 256 in it.
char m_list[256]; //array defined in class
m_list[0] = 0x00; //set first array index to zero
int count = 1; //count variable to step through the array and set members
while (count < 256)
{
m_list[count] = m_list[count -1] + 0x01; //populate array with hex from 0x00 - 0xFF
count++;
}
Next I created a function that lets me group my hex values into individual bytes and store into the array that will be processing my command.
void parse_input(char hex_array[], int i, char ans_array[])
{
int n = 0;
int j = 0;
int idx = 0;
string hex_values;
while (n < i-1)
{
if (hex_array[n] = '\0')
{
hex_values = '0';
}
else
{
hex_values = hex_array[n];
}
if (hex_array[n+1] = '\0')
{
hex_values += '0';
}
else
{
hex_values += hex_array[n+1];
}
cout<<"This is the string being used in stoi: "<<hex_values; //statement for testing
idx = stoul(hex_values, nullptr, 16);
ans_array[j] = m_list[idx];
n = n + 2;
j++;
}
}
This function will be called right after my previous code.
sprint(mychararray, %X, myintvalue);
void parse_input(arrayA, size of arrayA, arrayB)
Example: arrayA = 8byte char array, and arrayB is a 4byte char array. arrayA should be double the size of arrayB since you are taking two ascii values and making a byte pair. e.g 'A' 'B' = 0xAB
While I was trying to understand your question I realized what you needed was more than a single variable. You needed a class, this is because you wished to have a string that represents the hex code to be printed out and also the number itself in the form of an unsigned 16 bit integer, which I deduced would be something like unsigned short int. So I created a class that did all this for you named hexset (I got the idea from bitset), here:
#include <iostream>
#include <string>
class hexset {
public:
hexset(int num) {
this->hexnum = (unsigned short int) num;
this->hexstring = hexset::to_string(num);
}
unsigned short int get_hexnum() {return this->hexnum;}
std::string get_hexstring() {return this->hexstring;}
private:
static std::string to_string(int decimal) {
int length = int_length(decimal);
std::string ret = "";
for (int i = (length > 1 ? int_length(decimal) - 1 : length); i >= 0; i--) {
ret = hex_arr[decimal%16]+ret;
decimal /= 16;
}
if (ret[0] == '0') {
ret = ret.substr(1,ret.length()-1);
}
return "0x"+ret;
}
static int int_length(int num) {
int ret = 1;
while (num > 10) {
num/=10;
++ret;
}
return ret;
}
static constexpr char hex_arr[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
unsigned short int hexnum;
std::string hexstring;
};
constexpr char hexset::hex_arr[16];
int main() {
int number_from_file = 3000; // This number is in all forms technically, hex is just another way to represent this number.
hexset hex(number_from_file);
std::cout << hex.get_hexstring() << ' ' << hex.get_hexnum() << std::endl;
return 0;
}
I assume you'll probably want to do some operator overloading to make it so you can add and subtract from this number or assign new numbers or do any kind of mathematical or bit shift operation.

Converting an array of 2 digit numbers into an integer (C++)

Is it possible to take an array filled with 2 digit numbers e.g.
[10,11,12,13,...]
and multiply each element in the list by 100^(position in the array) and sum the result so that:
mysteryFunction[10,11,12] //The function performs 10*100^0 + 11*100^1 + 12*100^3
= 121110
and also
mysteryFunction[10,11,12,13]
= 13121110
when I do not know the number of elements in the array?
(yes, the reverse of order is intended but not 100% necessary, and just in case you missed it the first time the numbers will always be 2 digits)
Just for a bit of background to the problem: this is to try to improve my attempt at an RSA encryption program, at the moment I am multiplying each member of the array by 100^(the position of the number) written out each time which means that each word which I use to encrypt must be a certain length.
For example to encrypt "ab" I have converted it to an array [10,11] but need to convert it to 1110 before I can put it through the RSA algorithm. I would need to adjust my code for if I then wanted to use a three letter word, again for a four letter word etc. which I'm sure you will agree is not ideal. My code is nothing like industry standard but I am happy to upload it should anyone want to see it (I have also already managed this in Haskell if anyone would like to see that). I thought that the background information was necessary just so that I don't get hundreds of downvotes from people thinking that I'm trying to trick them into doing homework for me. Thank you very much for any help, I really do appreciate it!
EDIT: Thank you for all of the answers! They perfectly answer the question that I asked but I am having problems incorporating them into my current program, if I post my code so far would you be able to help? When I tried to include the answer provided I got an error message (I can't vote up because I don't have enough reputation, sorry that I haven't accepted any answers yet).
#include <iostream>
#include <string>
#include <math.h>
int returnVal (char x)
{
return (int) x;
}
unsigned long long modExp(unsigned long long b, unsigned long long e, unsigned long long m)
{
unsigned long long remainder;
int x = 1;
while (e != 0)
{
remainder = e % 2;
e= e/2;
if (remainder == 1)
x = (x * b) % m;
b= (b * b) % m;
}
return x;
}
int main()
{
unsigned long long p = 80001;
unsigned long long q = 70021;
int e = 7;
unsigned long long n = p * q;
std::string foo = "ab";
for (int i = 0; i < foo.length(); i++);
{
std::cout << modExp (returnVal((foo[0]) - 87) + returnVal (foo[1] -87) * 100, e, n);
}
}
If you want to use plain C-style arrays, you will have to separately know the number of entries. With this approach, your mysterious function might be defined like this:
unsigned mysteryFunction(unsigned numbers[], size_t n)
{
unsigned result = 0;
unsigned factor = 1;
for (size_t i = 0; i < n; ++i)
{
result += factor * numbers[i];
factor *= 100;
}
return result;
}
You can test this code with the following:
#include <iostream>
int main()
{
unsigned ar[] = {10, 11, 12, 13};
std::cout << mysteryFunction(ar, 4) << "\n";
return 0;
}
On the other hand, if you want to utilize the STL's vector class, you won't separately need the size. The code itself won't need too many changes.
Also note that the built-in integer types cannot handle very large numbers, so you might want to look into an arbitrary precision number library, like GMP.
EDIT: Here's a version of the function which accepts a std::string and uses the characters' ASCII values minus 87 as the numbers:
unsigned mysteryFunction(const std::string& input)
{
unsigned result = 0;
unsigned factor = 1;
for (size_t i = 0; i < input.size(); ++i)
{
result += factor * (input[i] - 87);
factor *= 100;
}
return result;
}
The test code becomes:
#include <iostream>
#include <string>
int main()
{
std::string myString = "abcde";
std::cout << mysteryFunction(myString) << "\n";
return 0;
}
The program prints: 1413121110
As benedek mentioned, here's an implementation using dynamic arrays via std::vector.
unsigned mystery(std::vector<unsigned> vect)
{
unsigned result = 0;
unsigned factor = 1;
for (auto& item : vect)
{
result += factor * item;
factor *= 100;
}
return result;
}
void main(void)
{
std::vector<unsigned> ar;
ar.push_back(10);
ar.push_back(11);
ar.push_back(12);
ar.push_back(13);
std::cout << mystery(ar);
}
I would like to suggest the following solutions.
You could use standard algorithm std::accumulate declared in header <numeric>
For example
#include <iostream>
#include <numeric>
int main()
{
unsigned int a[] = { 10, 11, 12, 13 };
unsigned long long i = 1;
unsigned long long s =
std::accumulate( std::begin( a ), std::end( a ), 0ull,
[&]( unsigned long long acc, unsigned int x )
{
return ( acc += x * i, i *= 100, acc );
} );
std::cout << "s = " << s << std::endl;
return 0;
}
The output is
s = 13121110
The same can be done with using the range based for statement
#include <iostream>
#include <numeric>
int main()
{
unsigned int a[] = { 10, 11, 12, 13 };
unsigned long long i = 1;
unsigned long long s = 0;
for ( unsigned int x : a )
{
s += x * i; i *= 100;
}
std::cout << "s = " << s << std::endl;
return 0;
}
You could also write a separate function
unsigned long long mysteryFunction( const unsigned int a[], size_t n )
{
unsigned long long s = 0;
unsigned long long i = 1;
for ( size_t k = 0; k < n; k++ )
{
s += a[k] * i; i *= 100;
}
return s;
}
Also think about using std::string instead of integral numbers to keep an encrypted result.