in python i do :
import random
while True:
x = random.randint(0xF,0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140)
print hex(x)[2:66].lower()
how to do that using C or C++ ?
Using GNU MP library, this can be done like this:
#include <stdio.h>
#include <ctype.h>
#include <gmp.h>
void randint(mpz_t rop, gmp_randstate_t state, mpz_t from, mpz_t to) {
mpz_t range;
mpz_init(range);
/* range = to - from + 1 */
mpz_sub(range, to, from);
mpz_add_ui(range, range, 1);
/* rop = random number in [0, range) */
mpz_urandomm(rop, state, range);
/* rop += from */
mpz_add(rop, rop, from);
mpz_clear(range);
}
int main(void) {
char str[1024]; /* allocate enough memory */
gmp_randstate_t state;
mpz_t low, high;
mpz_t ret;
gmp_randinit_default(state);
mpz_init(ret);
mpz_init_set_str(low, "F", 16);
mpz_init_set_str(high, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140", 16);
for(;;) {
randint(ret, state, low, high);
str[0]='0'; str[1]='x';
mpz_get_str(str + 2, 16, ret);
if (str[0] != '\0' && str[1] != '\0') {
int i;
for (i = 2; i < 66 && str[i] != '\0'; i++) putchar(tolower(str[i]));
}
putchar('\n');
}
/* the control won't come here */
#if 0
mpz_clear(low);
mpz_clear(high);
mpz_clear(ret);
gmp_randclear(state);
return 0;
#endif
}
A very simple solution:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define StringLength (256/4) // (Bits you want)/4 (Thanks, chux)
int main(void){
char cStrHex[(StringLength+1)] = {0};
// Seed random:
srand((unsigned int) time(0));
// Fill the char buffer
int i=0;
for(; i < StringLength; i++){
sprintf(cStrHex+i, "%x", rand() % 16);
}
// Print hex string:
printf("%s\n", cStrHex);
return 0;
}
Please note that rand() is not considered to be cryptographically secure, so replace calls to rand() with a CSPRNG if you want to use this for anything requiring completely unpredictable random number. Nonetheless, this is a short, simple, and efficient solution to your problem.
Here's an approach that uses random(). It attempts to use as many digits as possible. In case of POSIX random(), that's 31 bits, so 7 full digits. With, say, arc4random, you could use 8.
int max_usable_digits = 7;
uint64_t mask = (1 << (4 * max_usable_digits)) - 1;
const char *hex_digits = "0123456789abcdef";
std::string get_random_hex(int digits) {
char buffer[65] = {};
int offset = 0;
while (offset < sizeof(buffer)) {
long r = random() & mask;
offset += snprintf(buffer + offset, sizeof(buffer) - offset,
"%0*lx", max_usable_digits, r);
}
return std::string(buffer);
}
If you can use Boost library, generating_a_random_password example solves your problem with minor modifications.
UPDATE: This returns random strings between 64 zeros and 64 F's. The specific limits in OP's question (of 0xF and 0xFF..140) are a range of valid EDCSA keys. Nearly all 64-digit strings are valid. You can guarantee a number in the range with:
std::string min = "000000000000000000000000000000000000000000000000000000000000000F";
std::string max = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140";
std::string get_random_ecdsa_key() {
while (true) {
std::string s = get_random_hex(64);
if (s >= min && s < max) {
return s;
}
}
}
Related
I want to generate (pseudo) random numbers between 0 and some integer. I don't mind if they aren't too random. I have access to the current time of the day but not the rand function. Can anyone think of a sufficiently robust way to generate these? Perhaps, discarding some bits from time of day and taking modulo my integer or something?
I am using c.
If you're after an ultra-simple pseudo-random generator, you can just use a Linear Feedback shift Register.
The wikipedia article has some code snippets for you to look at, but basically the code for a 16-bit generator will look something like this (lightly massaged from that page...)
unsigned short lfsr = 0xACE1u;
unsigned bit;
unsigned rand()
{
bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1;
return lfsr = (lfsr >> 1) | (bit << 15);
}
For "not too random" integers, you could start with the current UNIX time, then use the recursive formula r = ((r * 7621) + 1) % 32768;. The nth random integer between 0 (inclusive) and M (exclusive) would be r % M after the nth iteration.
This is called a linear congruential generator.
The recursion formula is what bzip2 uses to select the pivot in its quicksort implementation. I wouldn't know about other purposes, but it works pretty well for this particular one...
Look at implementing a pseudo-random generator (what's "inside" rand()) of your own, for instance the Mersenne twister is highly-regarded.
#include <chrono>
int get_rand(int lo, int hi) {
auto moment = std::chrono::steady_clock::now().time_since_epoch().count();
int num = moment % (hi - lo + 1);
return num + lo;
}
The only "robust" (not easily predictable) way of doing this is writing your own pseudo-random number generator and seeding it with the current time. Obligatory wikipedia link: http://en.wikipedia.org/wiki/Pseudorandom_number_generator
You can get the "Tiny Mersenne Twister" here: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index.html
it is pure c and simple to use. E.g. just using time:
#include "tinymt32.h"
// And if you can't link:
#include "tinymt32.c"
#include <time.h>
#include <stdio.h>
int main(int argc, const char* argv[])
{
tinymt32_t state;
uint32_t seed = time(0);
tinymt32_init(&state, seed);
for (int i=0; i<10; i++)
printf("random number %d: %u\n", i, (unsigned int)tinymt32_generate_uint32(&state));
}
The smallest and simple random generator which work with ranges is provided below with fully working example.
unsigned int MyRand(unsigned int start_range,unsigned int end_range)
{
static unsigned int rand = 0xACE1U; /* Any nonzero start state will work. */
/*check for valid range.*/
if(start_range == end_range) {
return start_range;
}
/*get the random in end-range.*/
rand += 0x3AD;
rand %= end_range;
/*get the random in start-range.*/
while(rand < start_range){
rand = rand + end_range - start_range;
}
return rand;
}
int main(void)
{
int i;
for (i = 0; i < 0xFF; i++)
{
printf("%u\t",MyRand(10,20));
}
return 0;
}
If you're not generating your numbers too fast (*1) and your upper limit is low enough (*2) and your "time of day" includes nanoseconds, just use those nanoseconds.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int nanorand(void) {
struct timespec p[1];
clock_gettime(CLOCK_MONOTONIC, p);
return p->tv_nsec % 1000;
}
int main(void) {
int r, x;
for (;;) {
r = nanorand();
do {
printf("please type %d (< 50 quits): ", r);
fflush(stdout);
if (scanf("%d", &x) != 1) exit(EXIT_FAILURE);
} while (x != r);
if (r < 50) break;
}
puts("");
return 0;
}
And a sample run ...
please type 769 (< 50 quits): 769
please type 185 (< 50 quits): 185
please type 44 (< 50 quits): 44
(*1) if you're using them interactively, one at a time
(*2) if you want numbers up to about 1000
You can write your own rand() function. Like:
Method 1: Using the Concept of static variable:
example code:
int random_number_gen(int min_range, int max_range){
static int rand_number = 199198; // any random number
rand_number = ((rand_number * rand_number) / 10 ) % 9890;
return rand_number % (max_range+1-min_range) + min_range ;
}
Method 2. Using a random/unique value, for example, the current time in microseconds.
#include<time.h>
#include <chrono>
using namespace std;
uint64_t timeSinceEpochMicrosec() {
using namespace std::chrono;
return duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
}
int random_number_gen(int min_range, int max_range){
long long int current_time = timeSinceEpochMicrosec();
int current_time_in_sec = current_time % 10000000;
int rand_number = current_time_in_sec % (max_range+1-min_range) + min_range ;
return rand_number;
}
import java.io.*;
public class random{
public static class p{
}
static long reg=0;
static long lfsr()
{
if(reg==0)
{
reg=145896027340307l;
}
long bit=(reg>>0^reg>>2^reg>>3^reg>>5)&1;
reg=reg>>1|bit<<62;
return reg;
}
static long getRand()
{
String s=String.valueOf(new p());
//System.out.println(s);
long n=0;
lfsr();
for(int i=0;i<s.length();i++)
{
n=n<<8|+s.charAt(i);
}
System.out.print(n+" "+System.currentTimeMillis()+" "+reg+" ");
n=n^System.currentTimeMillis()^reg;
return n;
}
public static void main(String args[])throws IOException
{
for(int i=0;i<400;i++)
{
System.out.println(getRand());
}
}
}
This is a random number generator where it is guaranteed that the sequence never repeats itself. I have paired time with object value (randomly put by java) with LFSR.
Advantages:
The sequence doesn't repeat itself
The sequence is new on every run
Disadvantages:
Only compatible with java. In C++, new object that is created is same on every run.
But there too time and LFSR parameters would put in enough randomness
It is slower than most PRNGs as an object needs to be created everytime a number is needed
#include<time.h>
int main(){
int num;
time_t sec;
sec=time(NULL);
printf("Enter the Range under which you want Random number:\n");
scanf("%d",&num);
if(num>0)
{
for(;;)
{
sec=sec%3600;
if(num>=sec)
{
printf("%ld\n",sec);
break;
}
sec=sec%num;
}
}
else
{
printf("Please Enter Positive Value!\n");
}
return 0;
}
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int main()
{
unsigned int x,r,i;
// no of random no you want to generate
scanf("%d",&x);
// put the range of random no
scanf("%d",&r);
unsigned int *a=(unsigned int*)malloc(sizeof(unsigned int)*x);
for(i=0;i<x;i++)
printf("%d ",(a[i]%r)+1);
free(a);
getch();
return 0;
}
One of the simplest random number generator which not return allways the same value:
uint16_t simpleRand(void)
{
static uint16_t r = 5531; //dont realy care about start value
r+=941; //this value must be relative prime to 2^16, so we use all values
return r;
}
You can maybe get the time to set the start value if you dont want that the sequence starts always with the same value.
I write this code for show fibonacci series using recursion.But It not show correctly for n>43 (ex: for n=100 show:-980107325).
#include<stdio.h>
#include<conio.h>
void fibonacciSeries(int);
void fibonacciSeries(int n)
{
static long d = 0, e = 1;
long c;
if (n>1)
{
c = d + e;
d = e;
e = c;
printf("%d \n", c);
fibonacciSeries(n - 1);
}
}
int main()
{
long a, n;
long long i = 0, j = 1, f;
printf("How many number you want to print in the fibonnaci series :\n");
scanf("%d", &n);
printf("\nFibonacci Series: ");
printf("%d", 0);
fibonacciSeries(n);
_getch();
return 0;
}
The value of fib(100) is so large that it will overflow even a 64 bit number. To operate on such large values, you need to do arbitrary-precision arithmetic. Arbitrary-precision arithmetic is not provided by C nor C++ standard libraries, so you'll need to either implement it yourself or use a library written by someone else.
For smaller values that do fit your long long, your problem is that you use the wrong printf format specifier. To print a long long, you need to use %lld.
Code overflows the range of the integer used long.
Could use long long, but even that may not handle Fib(100) which needs at least 69 bits.
Code could use long double if 1.0/LDBL_EPSILON > 3.6e20
Various libraries exist to handle very large integers.
For this task, all that is needed is a way to add two large integers. Consider using a string. An inefficient but simply string addition follows. No contingencies for buffer overflow.
#include <stdio.h>
#include <string.h>
#include <assert.h>
char *str_revese_inplace(char *s) {
char *left = s;
char *right = s + strlen(s);
while (right > left) {
right--;
char t = *right;
*right = *left;
*left = t;
left++;
}
return s;
}
char *str_add(char *ssum, const char *sa, const char *sb) {
const char *pa = sa + strlen(sa);
const char *pb = sb + strlen(sb);
char *psum = ssum;
int carry = 0;
while (pa > sa || pb > sb || carry) {
int sum = carry;
if (pa > sa) sum += *(--pa) - '0';
if (pb > sb) sum += *(--pb) - '0';
*psum++ = sum % 10 + '0';
carry = sum / 10;
}
*psum = '\0';
return str_revese_inplace(ssum);
}
int main(void) {
char fib[3][300];
strcpy(fib[0], "0");
strcpy(fib[1], "1");
int i;
for (i = 2; i <= 1000; i++) {
printf("Fib(%3d) %s.\n", i, str_add(fib[2], fib[1], fib[0]));
strcpy(fib[0], fib[1]);
strcpy(fib[1], fib[2]);
}
return 0;
}
Output
Fib( 2) 1.
Fib( 3) 2.
Fib( 4) 3.
Fib( 5) 5.
Fib( 6) 8.
...
Fib(100) 3542248xxxxxxxxxx5075. // Some xx left in for a bit of mystery.
Fib(1000) --> 43466...about 200 more digits...8875
You can print some large Fibonacci numbers using only char, int and <stdio.h> in C.
There is some headers :
#include <stdio.h>
#define B_SIZE 10000 // max number of digits
typedef int positive_number;
struct buffer {
size_t index;
char data[B_SIZE];
};
Also some functions :
void init_buffer(struct buffer *buffer, positive_number n) {
for (buffer->index = B_SIZE; n; buffer->data[--buffer->index] = (char) (n % 10), n /= 10);
}
void print_buffer(const struct buffer *buffer) {
for (size_t i = buffer->index; i < B_SIZE; ++i) putchar('0' + buffer->data[i]);
}
void fly_add_buffer(struct buffer *buffer, const struct buffer *client) {
positive_number a = 0;
size_t i = (B_SIZE - 1);
for (; i >= client->index; --i) {
buffer->data[i] = (char) (buffer->data[i] + client->data[i] + a);
buffer->data[i] = (char) (buffer->data[i] - (a = buffer->data[i] > 9) * 10);
}
for (; a; buffer->data[i] = (char) (buffer->data[i] + a), a = buffer->data[i] > 9, buffer->data[i] = (char) (buffer->data[i] - a * 10), --i);
if (++i < buffer->index) buffer->index = i;
}
Example usage :
int main() {
struct buffer number_1, number_2, number_3;
init_buffer(&number_1, 0);
init_buffer(&number_2, 1);
for (int i = 0; i < 2500; ++i) {
number_3 = number_1;
fly_add_buffer(&number_1, &number_2);
number_2 = number_3;
}
print_buffer(&number_1);
}
// print 131709051675194962952276308712 ... 935714056959634778700594751875
Best C type is still char ? The given code is printing f(2500), a 523 digits number.
Info : f(2e5) has 41,798 digits, see also Factorial(10000) and Fibonacci(1000000).
Well, you could want to try implementing BigInt in C++ or C.
Useful Material:
How to implement big int in C++
For this purporse you need implement BigInteger. There is no such build-in support in current c++. You can view few advises on stack overflow
Or you also can use some libs like GMP
Also here is some implementation:
E-maxx - on Russian language description.
Or find some open implementation on GitHub
Try to use a different format and printf, use unsigned to get wider range of digits.
If you use unsigned long long you should get until 18 446 744 073 709 551 615 so until the 93th number for fibonacci serie 12200160415121876738 but after this one you will get incorrect result because the 94th number 19740274219868223167 is too big for unsigned long long.
Keep in mind that the n-th fibonacci number is (approximately) ((1 + sqrt(5))/2)^n.
This allows you to get the value for n that allows the result to fit in 32 /64 unsigned integers. For signed remember that you lose one bit.
I'm trying to find a way to find the length of an integer (number of digits) and then place it in an integer array. The assignment also calls for doing this without the use of classes from the STL, although the program spec does say we can use "common C libraries" (gonna ask my professor if I can use cmath, because I'm assuming log10(num) + 1 is the easiest way, but I was wondering if there was another way).
Ah, and this doesn't have to handle negative numbers. Solely non-negative numbers.
I'm attempting to create a variant "MyInt" class that can handle a wider range of values using a dynamic array. Any tips would be appreciated! Thanks!
Not necessarily the most efficient, but one of the shortest and most readable using C++:
std::to_string(num).length()
The number of digits of an integer n in any base is trivially obtained by dividing until you're done:
unsigned int number_of_digits = 0;
do {
++number_of_digits;
n /= base;
} while (n);
There is a much better way to do it
#include<cmath>
...
int size = trunc(log10(num)) + 1
....
works for int and decimal
If you can use C libraries then one method would be to use sprintf, e.g.
#include <cstdio>
char s[32];
int len = sprintf(s, "%d", i);
"I mean the number of digits in an integer, i.e. "123" has a length of 3"
int i = 123;
// the "length" of 0 is 1:
int len = 1;
// and for numbers greater than 0:
if (i > 0) {
// we count how many times it can be divided by 10:
// (how many times we can cut off the last digit until we end up with 0)
for (len = 0; i > 0; len++) {
i = i / 10;
}
}
// and that's our "length":
std::cout << len;
outputs 3
Closed formula for the longest int (I used int here, but works for any signed integral type):
1 + (int) ceil((8*sizeof(int)-1) * log10(2))
Explanation:
sizeof(int) // number bytes in int
8*sizeof(int) // number of binary digits (bits)
8*sizeof(int)-1 // discount one bit for the negatives
(8*sizeof(int)-1) * log10(2) // convert to decimal, because:
// 1 bit == log10(2) decimal digits
(int) ceil((8*sizeof(int)-1) * log10(2)) // round up to whole digits
1 + (int) ceil((8*sizeof(int)-1) * log10(2)) // make room for the minus sign
For an int type of 4 bytes, the result is 11. An example of 4 bytes int with 11 decimal digits is: "-2147483648".
If you want the number of decimal digits of some int value, you can use the following function:
unsigned base10_size(int value)
{
if(value == 0) {
return 1u;
}
unsigned ret;
double dval;
if(value > 0) {
ret = 0;
dval = value;
} else {
// Make room for the minus sign, and proceed as if positive.
ret = 1;
dval = -double(value);
}
ret += ceil(log10(dval+1.0));
return ret;
}
I tested this function for the whole range of int in g++ 9.3.0 for x86-64.
int intLength(int i) {
int l=0;
for(;i;i/=10) l++;
return l==0 ? 1 : l;
}
Here's a tiny efficient one
Being a computer nerd and not a maths nerd I'd do:
char buffer[64];
int len = sprintf(buffer, "%d", theNum);
Would this be an efficient approach? Converting to a string and finding the length property?
int num = 123
string strNum = to_string(num); // 123 becomes "123"
int length = strNum.length(); // length = 3
char array[3]; // or whatever you want to do with the length
How about (works also for 0 and negatives):
int digits( int x ) {
return ( (bool) x * (int) log10( abs( x ) ) + 1 );
}
Best way is to find using log, it works always
int len = ceil(log10(num))+1;
Code for finding Length of int and decimal number:
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int len,num;
cin >> num;
len = log10(num) + 1;
cout << len << endl;
return 0;
}
//sample input output
/*45566
5
Process returned 0 (0x0) execution time : 3.292 s
Press any key to continue.
*/
There are no inbuilt functions in C/C++ nor in STL for finding length of integer but there are few ways by which it can found
Here is a sample C++ code to find the length of an integer, it can be written in a function for reuse.
#include<iostream>
using namespace std;
int main()
{
long long int n;
cin>>n;
unsigned long int integer_length = 0;
while(n>0)
{
integer_length++;
n = n/10;
}
cout<<integer_length<<endl;
return 0;
}
Here is another way, convert the integer to string and find the length, it accomplishes same with a single line:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
long long int n;
cin>>n;
unsigned long int integer_length = 0;
// convert to string
integer_length = to_string(n).length();
cout<<integer_length<<endl;
return 0;
}
Note: Do include the cstring header file
The easiest way to use without any libraries in c++ is
#include <iostream>
using namespace std;
int main()
{
int num, length = 0;
cin >> num;
while(num){
num /= 10;
length++;
}
cout << length;
}
You can also use this function:
int countlength(int number)
{
static int count = 0;
if (number > 0)
{
count++;
number /= 10;
countlength(number);
}
return count;
}
#include <math.h>
int intLen(int num)
{
if (num == 0 || num == 1)
return 1;
else if(num < 0)
return ceil(log10(num * -1))+1;
else
return ceil(log10(num));
}
Most efficient code to find length of a number.. counts zeros as well, note "n" is the number to be given.
#include <iostream>
using namespace std;
int main()
{
int n,len= 0;
cin>>n;
while(n!=0)
{
len++;
n=n/10;
}
cout<<len<<endl;
return 0;
}
I am trying to convert a bit string (bitString) of length 'sLength' to an int.
The following code works fine for me in my computer. Is there any case where it may not work?
int toInt(string bitString, int sLength){
int tempInt;
int num=0;
for(int i=0; i<sLength; i++){
tempInt=bitString[i]-'0';
num=num+tempInt * pow(2,(sLength-1-i));
}
return num;
}
Thanks in advance
pow works with doubles. Result may be inaccurate. Use bit arithmetic instead
num |= (1 << (sLength-1-i)) * tempInt;
Don't also forget about cases when bitString contains symbols other than '0' and '1' or too long
Or, you can let the standard library do the heavy lifting:
#include <bitset>
#include <string>
#include <sstream>
#include <climits>
// note the result is always unsigned
unsigned long toInt(std::string const &s) {
static const std::size_t MaxSize = CHAR_BIT*sizeof(unsigned long);
if (s.size() > MaxSize) return 0; // handle error or just truncate?
std::bitset<MaxSize> bits;
std::istringstream is(s);
is >> bits;
return bits.to_ulong();
}
Why not change your for loop to the more efficient and far more simple C++11 version:
for (char c : bitString)
num = (num << 1) | // Shift the current set of bits to the left one bit
(c - '0'); // Add in the current bit via a bitwise-or
By the way, you should also check that the number of bits specified does not overrun an int and you may want to make sure that each char in the string is either a '0' or '1'.
Answer and notice about inaccuracy of floating-point numbers already given; here's a more readable implementation with integer arithmetic, though:
int toInt(const std::string &s)
{
int n = 0;
for (int i = 0; i < s.size(); i++) {
n <<= 1;
n |= s[i] - '0';
}
return n;
}
Notes:
You don't need an explicit length. That's why we have std::string::length().
Counting from zero results in cleaner code, because you don't have to do the subtraction every time.
for (std::string::reverse_iterator it = bitString.rbegin();
it != bitString.rend(); ++it) {
num *= 2;
num += *it == '1' ? 1 : 0;
}
I see directly three cases where it may not work :
pow Works with double, your result may be inaccurate, you can fix it with :
num |= tempInt * ( 1 << ( sLength - 1 - i ) );
If bitString[i] is not a '0' or '1',
If your number in the string in bigger than the int limit.
If you have control over the last two points, your resulting code could be :
int toInt( const string& bitString )
{
int num = 0;
for ( char c : bitString )
{
num <<= 1;
num |= ( c - '0' );
}
return num;
}
Don't forget the const reference as a parameter.
Code Taken From: Bytes to Binary in C Credit: BSchlinker
The following code I modified to take more than 1 Byte at a time. I modified it, and got it half working and then got really confused on my loops. :( Ive spent the last day and a half trying to figure it out... but my C++ skills are not really that good (still learning!)
#include <iostream>
using namespace std;
char show_binary(unsigned char u, unsigned char *result,int len);
int main()
{
unsigned char p40[3] = {0x40, 0x00, 0x0a};
unsigned char bits[8*(sizeof(p40))];
int c;
c=sizeof(p40);
show_binary(*p40, bits, 3);
cout << "\n\n";
cout << "BIN = ";
do{
for (int i = 0; i < 8; i++)
printf("%d",bits[i+(8*c)]);
c++;
}while(c < 3);
cout << "\n";
int a;
cin >> a;
return 0;
}
char show_binary(unsigned char u, unsigned char *result, int len)
{
unsigned char mask = 1;
unsigned char bits[8*sizeof(result)];
int a,b,c;
a=0;
b=0;
c=len;
do{
for (int i = 0; i < 8; i++)
bits[i+(8*a)] = (u[&a] & (mask << i)) != 0;
a++;
}while(a < len);
//Need to reverse it?
do{
for (int i = 8; i != -1; i--)
result[i+(8*c)] = bits[i+(8*c)];
b++;
c--;
}while(b < len);
return *result;
}
After I spit out:
cout << "BIN = ";
do{
for (int i = 0; i < 8; i++)
printf("%d",bits[i+(8*c)]);
c++;
}while(c < 3);
Id like to take bit[11] ~ bit[the end] and compute a BYTE every 8 bits. If that makes sense. But first the function should work. Any pro tips on how this should be done? And of course, rip my code apart. I like to learn.
Man, there is a lot going on in this code, so it's hard to know where to start. Suffice to say, you're trying a bit too hard. It sounds like you are trying to 1) pass in a byte array; 2) turn those bytes into a string representation of the binary; and 3) turn that string representation back into a value?
It just so happens I recently did something similar to this in C, which should still work using a C++ compiler.
#include <stdio.h>
#include <string.h>
/* A macro to get a substring */
#define substr(dest, src, dest_size, startPos, strLen) snprintf(dest, dest_size, "%.*s", strLen, src+startPos)
/* Pass in char* array of bytes, get binary representation as string in bitStr */
void str2bs(const char *bytes, size_t len, char *bitStr) {
size_t i;
char buffer[9] = "";
for(i = 0; i < len; i++) {
sprintf(buffer,
"%c%c%c%c%c%c%c%c",
(bytes[i] & 0x80) ? '1':'0',
(bytes[i] & 0x40) ? '1':'0',
(bytes[i] & 0x20) ? '1':'0',
(bytes[i] & 0x10) ? '1':'0',
(bytes[i] & 0x08) ? '1':'0',
(bytes[i] & 0x04) ? '1':'0',
(bytes[i] & 0x02) ? '1':'0',
(bytes[i] & 0x01) ? '1':'0');
strncat(bitStr, buffer, 8);
buffer[0] = '\0';
}
}
To get the string of binary back into a value it can by done with bit shifting:
unsigned char bs2uc(char *bitStr) {
unsigned char val = 0;
int toShift = 0;
int i;
for(i = strlen(bitStr)-1; i >= 0; i--) {
if(bitStr[i] == '1') {
val = (1 << toShift) | val;
}
toShift++;
}
return val;
}
Once you had a binary string you could then take substrings of any arbitrary 8 bits (or less, I guess) and turn them back into bytes.
char *bitStr; /* Let's pretend this is populated with a valid string */
char byte[9] = "";
substr(byte, bitStr, 9, 4, 8);
/* This would create a substring of length 8 starting from index 4 of bitStr */
unsigned char b = bs2uc(byte);
I've actually created a whole suite of value -> binary string -> value functions if you'd like to take a look at them. GitHub - binstr