go equivalents of c types - c++

What are the right equivalent of unsigned char or unsigned char* in go? Or am I even doing this right?
I have this C++ class:
class ArcfourPRNG
{
public:
ArcfourPRNG();
void SetKey(unsigned char *pucKeyData, int iKeyLen);
void Reset();
unsigned char Rand();
private:
bool m_bInit;
unsigned char m_aucState0[256];
unsigned char m_aucState[256];
unsigned char m_ucI;
unsigned char m_ucJ;
unsigned char* m_pucState1;
unsigned char* m_pucState2;
unsigned char m_ucTemp;
};
I am trying to rewrite it to go:
type ArcfourPRNG struct {
m_bInit bool
m_aucState0 [256]byte
m_aucState [256]byte
m_ucI, m_ucJ []byte
*m_pucState1 []byte
*m_pucState2 []byte
m_ucTemp []byte
}
func (arc4 *ArcfourPRNG) SetKey(pucKeyData []byte, iKeyLen int) {
func (arc4 *ArcfourPRNG) Reset() {
func (arc4 *ArcfourPRNG) Rand() uint {
Well, I just started with go a few hours ago. So this is still confusing me.
A function
for(i=0; i<256; i++)
{
m_pucState1 = m_aucState0 + i;
m_ucJ += *m_pucState1 + *(pucKeyData+m_ucI);
m_pucState2 = m_aucState0 + m_ucJ;
//Swaping
m_ucTemp = *m_pucState1;
*m_pucState1 = *m_pucState2;
*m_pucState2 = m_ucTemp;
m_ucI = (m_ucI + 1) % iKeyLen;
}
memcpy(m_aucState, m_aucState0, 256); // copy(aucState[:], aucState0) ?

Hopefully this can clear a few things up for you.
For storing raw sequences of bytes, use a slice []byte. If you know exactly how long the sequence will be, you can specify that, e.g. [256]byte but you cannot resize it later.
While Go has pointers, it does not have pointer arithmetic. So you will need to use integers to index into your slices of bytes.
For storing single bytes, byte is sufficient; you don't want a slice of bytes. Where there are pointers in the C++ code used to point to specific locations in the array, you'll simply have an integer index value that selects one element of a slice.
Go strings are not simply sequences of bytes, they are sequences of UTF-8 characters stored internally as runes, which may have different lengths. So don't try to use strings for this algorithm.
To reimplement the algorithm shown, you do not need either pointers or pointer arithmetic at all. Instead of keeping pointers into the byte arrays as you would in C++, you'll use int indexes into the slices.
This is kind of hard to follow since it's virtually all pointer arithmetic. I would want to have a description of the algorithm handy while converting this (and since this is probably a well-known algorithm, that should not be hard to find). I'm not going to do the entire conversion for you, but I'll demonstrate with hopefully a simpler example. This prints each character of a string on a separate line.
C++:
unsigned char *data = "Hello World";
unsigned char *ptr = 0;
for (int i = 0; i < std::strlen(data); i++) {
ptr = i + data;
std::cout << *ptr << std::endl;
}
Go:
data := []byte("Hello World")
for i := 0; i < len(data); i++ {
// The pointer is redundant already
fmt.Println(data[i:i+1])
}
So, learn about Go slices, and when you do reimplement this algorithm you will likely find the code to be somewhat simpler, or at least easier to understand, than its C++ counterpart.

Related

How to convert large number strings into integer in c++?

Suppose, I have a long string number input in c++. and we have to do numeric operations on it. We need to convert this into the integer or any possible way to do operations, what are those?
string s="12131313123123213213123213213211312321321321312321213123213213";
Looks like the numbers you want to handle are way to big for any standard integer type, so just "converting" it won't give you a lot. You have two options:
(Highly recommended!) Use a big integer library like e.g. gmp. Such libraries typically also provide functions for parsing and formatting the big numbers.
Implement your big numbers yourself, you could e.g. use an array of uintmax_t to store them. You will have to implement all sorts of arithmetics you'd possibly need yourself, and this isn't exactly an easy task. For parsing the number, you can use a reversed double dabble implementation. As an example, here's some code I wrote a while ago in C, you can probably use it as-is, but you need to provide some helper functions and you might want to rewrite it using C++ facilities like std::string and replacing the struct used here with a std::vector -- it's just here to document the concept
typedef struct hugeint
{
size_t s; // number of used elements in array e
size_t n; // number of total elements in array e
uintmax_t e[];
} hugeint;
hugeint *hugeint_parse(const char *str)
{
char *buf;
// allocate and initialize:
hugeint *result = hugeint_create();
// this is just a helper function copying all numeric characters
// to a freshly allocated buffer:
size_t bcdsize = copyNum(&buf, str);
if (!bcdsize) return result;
size_t scanstart = 0;
size_t n = 0;
size_t i;
uintmax_t mask = 1;
for (i = 0; i < bcdsize; ++i) buf[i] -= '0';
while (scanstart < bcdsize)
{
if (buf[bcdsize - 1] & 1) result->e[n] |= mask;
mask <<= 1;
if (!mask)
{
mask = 1;
// this function increases the storage size of the flexible array member:
if (++n == result->n) result = hugeint_scale(result, result->n + 1);
}
for (i = bcdsize - 1; i > scanstart; --i)
{
buf[i] >>= 1;
if (buf[i-1] & 1) buf[i] |= 8;
}
buf[scanstart] >>= 1;
while (scanstart < bcdsize && !buf[scanstart]) ++scanstart;
for (i = scanstart; i < bcdsize; ++i)
{
if (buf[i] > 7) buf[i] -= 3;
}
}
free(buf);
return result;
}
Your best best would be to use a large numbers computational library.
One of the best out there is the GNU Multiple Precision Arithmetic Library
Example of a useful function to solve your problem::
Function: int mpz_set_str (mpz_t rop, const char *str, int base)
Set the value of rop from str, a null-terminated C string in base
base. White space is allowed in the string, and is simply ignored.
The base may vary from 2 to 62, or if base is 0, then the leading
characters are used: 0x and 0X for hexadecimal, 0b and 0B for binary,
0 for octal, or decimal otherwise.
For bases up to 36, case is ignored; upper-case and lower-case letters
have the same value. For bases 37 to 62, upper-case letter represent
the usual 10..35 while lower-case letter represent 36..61.
This function returns 0 if the entire string is a valid number in base
base. Otherwise it returns -1.
Documentation: https://gmplib.org/manual/Assigning-Integers.html#Assigning-Integers
If string contains number which is less than std::numeric_limits<uint64_t>::max(), then std::stoull() is the best opinion.
unsigned long long = std::stoull(s);
C++11 and later.

Copy memory from char* to a location in larger char*

I am trying to create code that places half a dozen variables into a char* and they are almost all multi-byte variables. Since they are all going into the same char* I'd like to be able to copy the data into the char* as easily as possible.
If there is no "standard" way for me to do this, I can easily make an inline function that deals with this for me. I was, however, hoping there would be a simple way of doing this, perhaps like:
memcpy(char* target, char* source, int target_start_position, int source_length)
So to elaborate on that:
I'd be copying all the data from source, into target. I'd copy the data to target[target_start_position] Then source_length would merely be for the function to know how much data it is going to be reading from the source.
What I actually tried. Perhaps you can see what my thought process was however.
=================
This is as simple as I was hoping to get things:
(Which I realize doesn't work because I am assigning pointers as values)
char* data;
unsigned __int64 pos = 0;
int string_len = sName.size();
unsigned __int64 data_size = sizeof(string_len) + string_len + (sizeof(int) * 10) + 3;
data = new char[data_size];
data[pos] = (char const*)(&string_len);
pos += sizeof(string_len);
data[pos] = (char const*)(&sName);
pos += string_len;
data[pos] = (char const*)(&iStatPoints);
pos += sizeof(int);
Note: I apologize for the title, that was the most precise way of describing the issue I could think of.
you can get the desired affect with pointer arithmetic. For example your desired function could be implemented as follows:
void *memcpy2(void *dest, const void *src, size_t offset, size_t length) {
return memcpy((char*)dest + offset, src, length);
}

How can I add multiple ints to a character array, then pull them out?

I am trying to place 3 integers(byte size is 4) into a character string byte by byte using c. I then need to "extract" the integers out of the character array so I can do integer operations on them. I have looked around and could not find any solutions to this. I think this will require some type of pointer use or shifting, but I cannot figure out how to write it.
char str[12]="";
int a;
int b;
int c;
int x;
int y;
int z;
a=5;
b=7;
c=12;
I know that an int is 4 bytes. I would like to make it so the str char array has the following data in it.
str = |a1|a2|a3|a4|b1|b2|b3|b4|c1|c2|c3|c4|
*I do not want it like this. str=|'5'|'7'|'12'|
I then need to "extract" the integers out of the character array.
x=str[0-3]; //extracting a
y=str[4-7]; //extracting b
z=str[8-11]; //extracting c
After this, I should be able to write x=y+z and x will be equal to 19.
One way is to treat str as an int array instead:
int* istr = reinterpret_cast<int*>(str)
Then you can use e.g.
istr[0] = a;
istr[1] = b;
istr[2] = c;
and
x = istr[0];
y = istr[1];
z = istr[2];
The question is not well posed so you are getting different answers which may or may not be solving your problem. In my interpretation, here's what you need:
int i1, i2, i3;
char arr[sizeof(i1)+sizeof(i2)+sizeof(i3)];
memcpy(arr, &i1, sizeof(i1));
memcpy(arr+sizeof(i1), &i2, sizeof(i2));
memcpy(arr+sizeof(i1)+sizeof(i2), &i3, sizeof(i3));
Note that I'm being deliberately explicit with using sizeof(i) instead of just "4". It is fairly safe that integers will be 32-bit in whatever environment you are using, but this is safer and strictly speaking more correct.
The easiest solution is to use memcpy:
int nums[sizeof str / sizeof(int)];
std::memcpy(nums, str, sizeof nums);
// Do work on nums here...
The reinterpret_cast approach is undefined behaviour.
Use (void *) to get a pointer to x, byte by byte
for (int i = 0; i < sizeof(int); ++i) {
str[i] = (void *)(&x)[i];
}
This will copy the 4 bytes of x into str, one by one. (void )(&x) casts x as a char array (or void*, same thing), and [i] accesses the i_th byte of the array
then access elements of str the same way.
Do the same with y and z, and don't forget the offset

Convert Int to Char Array

I need to make a class called MyInt which handles any size positive numbers by creating an int array. I am making a constructor to be used in converting an int (any size supported by ints) into a MyInt. I need to convert the int into a char array and then read digit by digit into the int array. So my question is, without using any libraries except <iostream> <iomanip> and <cstring> how can I convert an int with multiple digits into a character array?
You don't need to make a char array as an intermediary step. The digits (I assume in base 10) can be obtained one by one using modulo 10 operations. Something like:
convert(int *ar, const int i)
{
int p, tmp;
tmp = i
while (tmp != 0)
{
ar[p] = tmp % 10;
tmp = (tmp - ar[p])/10;
p++;
}
}
Not sure if this is what you want, but:
int myInt = 30;
char *chars = reinterpret_cast<char*>(&myInt);
And you can get the 4 separate char's:
chars[0]; // is the first char
chars[1]; // is the second char
chars[2]; // is the third char, and
chars[3]; // is the fourth/last char
...but I'm not entirely sure if that's what you are looking for.
One possible way of doing that conversion with such restraints is as follows:
function convert:
//find out length of integer (integer division works well)
//make a char array of a big enough size (including the \0 if you need to print it)
//use division and modulus to fill in the array one character at a time
//if you want readable characters, don't forget to adjust for them
//don't forget to set the null character if you need it
I hope I didn't misunderstand your question, but that worked for me, giving me a printable array that read the same as the integer itself.

Using pointer for crossing over all elements in INTEGER array

Is there a way to cross over all elements in integer array using pointer ( similiar to using pointer to cross over string elements).I know that integer array is not NULL terminated so when I try to cross over array using pointer it overflows.So I added NULL as a last element of an array and it worked just fine.
int array[7]={1,12,41,45,58,68,NULL};
int *i;
for(i=array;*i;i++)
printf("%d ",*i);
But what if one of the elements in array is 0 ,that will behave just as NULL.Is there any other way that will implement pointer in crossing over all elements in integer array?
In general, no unless you pick a sentinel value that's not part of the valid range of the data. For example, the valid range might be positive numbers, so you can use a negative number like -1 as a sentinel value that indicates the end of the array. This how C-style strings work; the NULL terminator is used because it's outside of the valid range of integers that could represent a character.
However, it's usually better to somehow pair up the array pointer with another variable that indicates the size of the array, or another pointer that points one-past-the-end of the array.
In your specific case, you can do something like this:
// Note that you don't have to specify the length of the array.
int array[] = {1,12,41,45,58,68};
// Let the compiler count the number of elements for us.
int arraySize = sizeof(array)/sizeof(int);
// or int arraySize = sizeof(array)/sizeof(array[0]);
int main()
{
int* i;
for(i = array; i != array + arraySize; i++)
printf("%d ",*i);
}
You can also do this:
int arrayBegin[] = {1,12,41,45,58,68};
int* arrayEnd = arrayBegin + sizeof(arrayBegin)/sizeof(arrayBegin[0]);
int main()
{
int* i;
for(i = arrayBegin; i != arrayEnd; i++)
printf("%d ",*i);
}
But given only a pointer, no you can't know how long the array it points to is. In fact, you can't even tell if the pointer points to an array or a single object! (At least not portably.)
If you have functions that must accept an array, either have your function require:
the pointer and the size of the array pointed by the pointer,
or two pointers with one pointing to the first element of the array and one pointing one-past-the-end of the array.
I'd like to give some additional advice: Never use some kind of sentinel/termination value in arrays for determining their bounds. This makes your programs prone to error and is often the cause for security issues. You should always store the length of arrays to limit all operations to their bounds and test against that value.
In C++ you have the STL and its containers.
In C you'll effectively end up using structures like
typedef struct t_int_array
{
size_t length;
int data[1]; /* note the 1 (one) */
} int_array;
and a set of manipulation functions like this
int_array * new_int_array(size_t length)
{
int_array * array;
/* we're allocating the size of basic t_int_array
(which already contains space for one int)
and additional space for length-1 ints */
array = malloc( sizeof(t_int_array) + sizeof(int) * (length - 1) );
if(!array)
return 0;
array->length = length;
return array;
}
int_array * concat_int_arrays(int_array const * const A, int_array const * const B);
int_array * int_array_push_back(int_array const * const A, int const value);
/* and so on */
This method will make the compiler align the t_int_array struct in a way, that it's optimal for the targeted architecture (also with malloc allocation), and just allocating more space in quantities of element sizes of the data array element will keep it that way.
The reason that you can iterate across a C-style string using pointers is that of the 256 different character values, one has been specifically reserved to be interpreted as "this is the end of the string." Because of this, C-style strings can't store null characters anywhere in them.
When you're trying to use a similar trick for integer arrays, you're noticing the same problem. If you want to be able to stop at some point, you'll have to pick some integer and reserve it to mean "this is not an integer; it's really the end of the sequence of integers." So no, there is no general way to take an array of integers and demarcate the end by a special value unless you're willing to pick some value that can't normally appear in the string.
C++ opted for a different approach than C to delineate sequences. Instead of storing the elements with some sort of null terminator, C++-style ranges (like you'd find in a vector, string, or list) store two iterators, begin() and end(), that indicate the first element and first element past the end. You can iterate over these ranges by writing
for (iterator itr = begin; itr != end; ++itr)
/* ... visit *itr here ... */
This approach is much more flexible than the C-string approach to defining ranges as it doesn't rely on specific properties of any values in the range. I would suggest opting to use something like this if you want to iterate over a range of integer values. It's more explicit about the bounds of the range and doesn't run into weird issues where certain values can't be stored in the range.
Apart from the usual suggestion that you should go and use the STL, you can find the length of a fixed array like this:
int array[6]={1,12,41,45,58,68};
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
{ }
If you use a templated function, you can implicitly derive the length like this:
template<size_t len> void func(int (&array)[len])
{
for (int i = 0; i < len; ++i) { }
}
int array[6]={1,12,41,45,58,68};
func(array);
If 0 is a value that may occur in a normal array of integers, you can specify a different value:
const int END_OF_ARRAY = 0x80000000;
int array[8]={0,1,12,41,45,58,68,END_OF_ARRAY};
for (int i = 0; array[i] != END_OF_ARRAY; ++i)
{ }
If every value is a possibility, or if none of the other approaches will work (for example, a dynamic array) then you have to manage the length separately. This is how strings that allow embedded null characters work (such as BSTR).
In your example you are using (or rather abusing) the NULL macro as a sentinel value; this is the function of the NUL('\0') character in a C string, but in the case of a C string NUL is not a valid character anywhere other than as the terminal (or sentinel) value .
The NULL macro is intended to represent an invalid pointer not an integer value (although in C++ when implicitly or explicitly cast to an int, its value is guaranteed to be zero, and in C this is also almost invariably the case). In this case if you want to use zero as the sentinel value you should use a literal zero not NULL. The problem is of course that if in this application zero is a valid data value it is not suitable for use as a sentinel.
So for example the following might suit:
static const int SENTINEL_VALUE = -1 ;
int array[7] = { 1, 12, 41, 45, 58, 68, SENTINEL_VALUE } ;
int* i ;
for( i = array; *i != SENTINEL_VALUE; i++ )
{
printf( "%d ", *i ) ;
}
If all integer values are are valid data values then you will not be able to use a sentinel value at all, and will have to use either a container class (which knows its length) or iterate for the known length of the array (from sizeof()).
Just to pedanticize and expand a little on a previous answer: in dealing with integer arrays in C, it's vanishingly rare to rely on a sentinel value in the array itself. No(1) sane programmer does that. Why not? Because by definition an integer can hold any value within predefined negative/positive limits, or (for the nowadays-not-unusual 32-bit integer) 0 to 0xffffff. It's not a good thing to redefine the notion of "integer" by stealing one of its possible values for a sentinel.
Instead, one always(1) must(1) rely on a controlling up-to-date count of integers that are in the array. Suppose we are to write a C function
that returns an int pointer to the first array member whose value is greater than the function's argument or, if there's no such member, returns NULL (all code is untested):`
int my_int_array[10]; // maximum of 10 integers in my_int_array[], which must be static
int member_count = 0; // varies from 0 to 10, always holds number of ints in my_int_array[]
int *
first_greater_than ( int val ) {
int i;
int *p;
for ( i = 0, p = my_int_array; i < member_count; ++i, ++p ) {
if ( *p > val ) {
return p;
}
}
return NULL;
}
Even better is also to limit the value of i to never count past the last possible member of my_int_array[], i.e., it never gets bigger than 9, and p never points at my_int_array[10] and beyond:
int my_int_array[10]; // maximum of 10 integers in my_int_array[], which must be static
int member_count = 0; // varies from 0 to 10, always holds number of ints in my_int_array[]
int *
first_greater_than ( int val ) {
#define MAX_COUNT sizeof(my_int_array)/sizeof(int)
int i;
int* p;
for ( i = 0, p = my_int_array; i < member_count && i < MAX_COUNT; ++i, ++p ) {
if ( *p > val ) {
return p;
}
}
return NULL;
}
HTH and I apologize if this is just too, too elementary.
--pete
Not strictly true but believe it for now
In ANSI C it's very easy and shorter than solution before:
int array[]={1,12,41,45,58,68}, *i=array;
size_t numelems = sizeof array/sizeof*array;
while( numelems-- )
printf("%d ",*i++);
Another way is to manage array of pointers to int:
#include <stdlib.h>
#include <stdio.h>
#define MAX_ELEMENTS 10
int main() {
int * array[MAX_ELEMENTS];
int ** i;
int k;
// initialize MAX_ELEMENTS,1 matrix
for (k=0;k<MAX_ELEMENTS;k++) {
array[k] = malloc(sizeof(int*));
// last element of array will be NULL pointer
if (k==MAX_ELEMENTS-1)
array[k] = NULL;
else
array[k][0] = k;
}
// now loop until you get NULL pointer
for (i=array;*i;i++) {
printf("value %i\n",**i);
}
// free memory
for (k=0;k<MAX_ELEMENTS;k++) {
free(array[k]);
}
return 0;
}
In this way loop condition is totally independent from the values of integers. But... for this to work you must use 2D array (matrix) instead of ordinary 1D array. Hope that helps.