c - printf("%s") prints an additional # - c

I am right know working on the cs50 programming tutorial. Here I should crack a DES-encrypted string.
First I concentrate on the creating a 64bit big array with all possible chars used in the salt.
In the next step, I throw this into two for loops to print out all possible combinations of those two for loops. And that's where I am at right now.
For debug reasons, I did just print it out with printf("%s",salt). Salt is defined as char salt[2]. But for some reason, it always prints out xx# (xx changes every time as expected, I have no idea where the # is coming from).
First I thought it might overshoot the array for some weird reason and grab the # from random memory. This is why I copied it from my online IDE into my local XCode. Still the same # symbol. And now I am confused from where the # is coming from.
Link to my code.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define _XOPEN_SOURCE // DES - implementation
#include <unistd.h>
// shorthands
#define cypher argv[1]
#define ascii_dot 46
#define ascii_slash 47
#define ascii_zero 48
#define ascii_nine 57
#define salt_size 64
#define majA 65
#define majZ 90
#define minA 97
#define minZ 122
int main(int argc, string argv[]) {
// Checking input
if (argc != 2) {
printf("<usage>\n<./crack <password_hash>");
return 1;
}
// Create a salter
// 2 * 26 for letters + 10 for numbers + dot and slash = 64 = salt_size
char salt_crystal[salt_size];
{ // Own scope to not waste space for salt_iterator
int salt_iterator = 0; // used to create salt crystals
//minuscels
for (int i = minA; i <= minZ; i++)
salt_crystal[salt_iterator++] = (char)i;
//majuscels
for (int i = majA; i <= majZ; i++)
salt_crystal[salt_iterator++] = (char)i;
//ascii_dot to 9
for (int i = ascii_dot; i <= ascii_nine; i++)
salt_crystal[salt_iterator++] = (char) i;
}
// make the salt and forward it to the next function
for (int i = 0, l = salt_size; i < l; i++) {
char salt[2];
salt[0] = salt_crystal[i];
for (int i2 = 0, l2 = salt_size; i2 < l2; i2++) {
salt[1] = salt_crystal[i2];
printf("%s ", salt); // DEBUG
}
}
}

You have not posted any code, but I'm guessing you did not null terminate the array you pass to printf()...
EDIT Good guess: You set 2 characters into char salt[2] and pass that to printf. printf prints those and continues to read characters from memory beyond the end of the salt array until it finds a '\0' byte that ends the string.
There are different ways to fix this:
you can make the array longer and set a '\0' after the characters:
char salt[3];
...
salt[2] = '\0';
printf("%s", salt);
you can use a precision value of 2 in the printf format to print at most 2 bytes from the array:
printf("%.2s", salt);
you can print individual bytes from the array:
putchar(salt[0]);
putchar(salt[1]);
As to why you consistently get an #, there is no definite answer because you are experiencing undefined behavior, so anything can happen... Note however that # has value 64 which is the value you store into local variable l. It is possible that the salt array is positioned in memory juste before the l variable. In little endian, the value 64 is stored in the first byte of l.
Also note that the name l is not recommended for a variable because it is difficult to distinguish from the number 1 in a fixed font such as this.

Related

Multi-Dimensional Arrays with Char / pointer Issues Writing to Curses

Newbie C programmer (experienced in other high level languages) and I'm still struggling to get used to arrays, pointers vs strings etc.
This project is recreating something I did in python. I am storing a character set (7 lines high by 6 wide) in an array. The array is multi-dimensional to store all the lines of all the characters referenced by their corresponding ascii code - array structure: font[ascii_code][line]. See code below for clarity.
The main loop will read one character from the message, look up it's corresponding ascii code in the font array and write out a column at a time to another array which is sort of a matrix of all screen positions. That matrix array then gets written to the screen with curses. Then we shift all cols of the matrix to the left and loop again. This effectively creating a leftward scroll text. Once we finish all 6 cols of a character from the font array we increment the message position, get the next message character and loop again.
My issues (I am sure because I am still learning the intricate ways of c programming):
I get an incredible amount of 'integer from pointer without a cast' errors which I believe is to do with referencing a string rather than a pointer to a string, but I'm struggling to understand this. I have been putting & in front of array references - it seems to sometimes work but not others.
I also don't understand why a declaration like
char cur_char = ' ';
works fine but this does not:
char msg = "This is a message";
but this does:
char msg[] = "This is a message";
I read that I should use single quotes for a single character and double quotes for a string. I understand that chars are really arrays of ascii values but why it's necessary to declare with the brackets I don't really understand.
Again calling the curses function like this:
mvaddch(1, 74, " ");
gets me an 'integer from pointer' error. I was hoping to draw a space at row 1 col 74. If this function expects a pointer rather than a string, does that mean it's necessary to store a space in a char and then pass the pointer of that char to the function? I'm trying to figure out the proper approach here.
Finally, I am just after some guidance from more experienced c programmers as to a logical approach to this. Maybe storing all these strings in a large array is not the way to do it. Is it possible (practical) to put this character set in memory and reference it that way?
Any suggestions, tips and advice, gratefully and humbly accepted. Appreciate your eyeballs and I am determined to master this language!
Bonus round
Originally I tried loading in my character set array from a function in a header file so I wouldn't have all these ugly data lines in the main c file. Gave up because I couldn't pass arrays back as a function return value. I am sure there's a better way. How would you split it out?
Here's the code:
Still getting errors on:
mvaddch(l, m, scr_matrix[l][m]); // makes integer from pointer error;
strcpy(scr_matrix[l][m], &scr_matrix[l][m + 1]); // incompatible pointer type
Here is a test version of my code. Put comments in for clarity.
#include <curses.h>
#include <unistd.h> // For sleep()
#include <string.h> // For strlen()
#include <stdlib.h> // For malloc()
int main(int argc, char* argv[])
{
// Let's initialise constants and set some configs
char msg[] = "XYZ";
int msg_length;
int i, j, k, l, m;
int msg_pos = 0;
int char_pos = 0;
char cur_char = ' ';
// Array to make a matrix that we will draw to screen with curses
char scr_matrix[7][76][2]; // Our lines (7) and cols (76) positions in an array
// Lets just initalise all the array elements to contain spaces
for (i = 0; i < 14; i++) {
for (j = 0; j < 75; j++) {
strcpy(scr_matrix[i][j], " "); //Have to use strcpy because can't set element
}
}
// char font array to hold our char set
char font2[100][7][7]; // 100 chars, 7 tall by 6 wide (+ /0 makes 7)
// Set array elements - first element correspond to char ascii code
// glyphs are 7 lines tall by 6 wide
// Use strcpy because cannot directly set elements?
strcpy(font2[88][0], "## ##");
strcpy(font2[88][1], "## ##");
strcpy(font2[88][2], " #### ");
strcpy(font2[88][3], " ## ");
strcpy(font2[88][4], " #### ");
strcpy(font2[88][5], "## ##");
strcpy(font2[88][6], "## ##");
strcpy(font2[89][0], "## ##");
strcpy(font2[89][1], "## ##");
strcpy(font2[89][2], " #### ");
strcpy(font2[89][3], " #### ");
strcpy(font2[89][4], " ## ");
strcpy(font2[89][5], " ## ");
strcpy(font2[89][6], " ## ");
strcpy(font2[90][0], "######");
strcpy(font2[90][1], "######");
strcpy(font2[90][2], " ## ");
strcpy(font2[90][3], " ## ");
strcpy(font2[90][4], " ## ");
strcpy(font2[90][5], "######");
strcpy(font2[90][6], "######");
// Get msg length
msg_length = strlen(msg);
// Initialize screen for curses
initscr();
// Hide the cursor with curses
curs_set(0);
for (i = 0; i < msg_length; i++) {
cur_char = msg[msg_pos]; // keep track of which char from msg we are working on
// Loop for 6 cols - 6 for glyph width
for (j = 0; j < 7; j++) {
clear(); // Clear the screen with curses
// Loop for 7 lines - writing 1 char of the glyph to the matrix
for (k = 0; k < 7; k++) {
// cpy the character from font array into the matrix array
strcpy(scr_matrix[k][74], &font2[cur_char][k][j]);
}
// Now add all matrix positions to the screen with curses mvaddch
// Loops through all positions in scroll area
for (l = 0; l < 7; l++) {
for (m = 0; m < 75; m++) {
mvaddch(l, m, scr_matrix[l][m]); // add to screen with curses
// now shift this character in the matrix over by -1 col so it shifts left
strcpy(scr_matrix[l][m], &scr_matrix[l][m + 1]);
}
}
// Now draw the screen as built by curses with mvaddch
refresh();
// Wait a bit - pause for timing purpose
usleep(80000);
} // Back to top of loop for the next col
// Finished the glyph so add a col of spaces for kerning between letters
for (l = 0; l < 7; l++) {
mvaddch(l, 74, " ");
refresh();
usleep(80000);
}
msg_pos++;
}
// Clean up our curses screen
endwin();
return 0;
}
The problem comes from the fact that C was basically crated without type safety and types checks were added later on, when some convinience syntax was alredy in place.
The convinience feature is that the name of an array can be used as a pointer to the first element if the indexing is left away.
char array[10];
char two_dim_array[10][20];
char *charpointer;
charpointer = array; /* leaving the index away, so pointer to first element */
charpointer = &array[0]; /* basically the same */
charpointer = two_dim_array[3]; /* is short for */
charpointer = &two_dim_array[3][0]; /* this */
But if you use an array variable without index in sizeof or the address operator the compiler still knows it's an array.
char array[10];
char two_dim_array[10][20];
int size;
char *charpointer;
size = sizeof(array); /* 10 */
size = sizeof(two_dim_array[3]); /* 20 */
charpointer = &two_dim_array[10]; /* wrong pointer type, address of array of 20 char */
To your Errors from the compiler:
mvaddch(l, m, scr_matrix[l][m]); // makes integer from pointer error;
As scr_matrix is declared as char scr_matrix[7][76][2];
scr_matrix[l][m] is a pointer to the fist byte of the string, of the lowest level array. The Compiler complains as mvaddch expects the integer code of the character scr_matrix[l][m][0] would be fine.
strcpy(scr_matrix[l][m], &scr_matrix[l][m + 1]); // incompatible pointer type
Here the second parameter is
&scr_matrix[l][m + 1] the address of an array of 2 charaters.
Expected is a pointer to a character scr_matrix[l][m + 1] would be fine.
explanation
char cur_char = ' ';
works fine becuase '<char>' is a single (8 bit) character literal. char is a data type that stores an 8-bit character
This doesnt work
char msg = "This is a message";
because char only holds one character.
Sidebar: character strings in c:-
a character string in c is an contiguous array of 8-bit chars follows by a byte of 0
so this "Hello" is stored in memory as
x48x65x6cx6cx6fx00
H e l l o
OK so what this
char msg[] = "Hello";
does is creates a 6 (note the +1 for the 0) byte array on the stack and loads the letters Hello into it and adds the 0.
this does something quite different
char *msg = "Hello";
this creates a 6 byte character array as a literal (usualy in the code segment) and the creates a pointer of the stack (called msg) and sets it to point at that literal
Hope this helps.

identify bits set in bitmap and print them in string

given a unsigned 64 bit integer.
which has multiple bits set in it.
want to process the bitmap and identify the position and return the string according to the position where bit is it.
example: unsigned integer is 12. means 1100 which implies third bit and fourth bit are set. this should print THREE FOUR
function takes unsigned int and returns string.
I looked some pieces of code and i don't see this as a dup of some other question.
char* unsigned_int_to_string(unsigned long int n)
{
unsigned int count = 0;
while(n)
{
int i, iter;
count += n & 1;
n >>= 1;
}
/*** Need help to fill this block ***/
/** should return string THREE FOUR***/
}
#include <stdio.h>
int main()
{
unsigned long int i = 12;
printf("%s", unsigned_int_to_sring(i));
return 0;
}
You could brute force it by having a lookup table which has a word representation for each bit you're interested in.
char* bit_to_word[10] = { "ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE","TEN" }; // and so forth...
Then in your function check every bit and if it is set, concatenate the corresponding word from your bit_to_word array. You can safely do this by using the strcat_s function.
strcat_s(number_string, BUF_SIZE, bit_to_word[i]);
One gotcha. After the first word you will want to add a space as well so you might want to keep track of that.
This code checks the first 10 bits of the number and prints out THREE FOUR for the test case. Be aware though that it doesn't do any memory cleanup.
#include <stdio.h>
#include <string.h>
#define BUF_SIZE 2048
char* bit_to_word[10] = { "ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE","TEN" };
char* unsigned_int_to_string(unsigned long int n)
{
char* number_string = (char*)malloc(BUF_SIZE);
memset(number_string, 0, BUF_SIZE);
int first_word = 1;
unsigned long int tester = 1;
int err;
for (unsigned long int i = 0; i < 10; i++)
{
if (tester & n)
{
if (!first_word)
{
strcat_s(number_string, BUF_SIZE, " ");
}
err = strcat_s(number_string, BUF_SIZE, bit_to_word[i]);
if (err)
{
printf("Something went wrong...\n");
}
first_word = 0;
}
tester <<= 1;
}
return number_string;
}
int main(int argc, char** argv)
{
char* res = unsigned_int_to_string(0b1100);
printf("%s\n", res);
}
Without writing the actual code, here is the description of a simple algorithm based on a 64 element lookup table of strings. 0 = ZERO, 1 = ONE, 2 = TWO ... 63 = SIXTY THREE. This table will be a 64 element array of strings. For C, you could make a static 2D array using char[256] to hold your strings (or optimize by using the value of the largest string + 1), or you could make a dynamic using malloc in a For Loop)
You then define your output string.
You then write a For Loop, iterating through all the bits using a bit mask (using left shift) if the Bit is set you can concatenate your output string (using strcat) with a space and the contents of your lookup table for that bit position.
Here is a brief code snippet on how you will do the concatenation: (Make sure you output string has enough memory in the outputstring variable to hold the largest string. If you want to be more sophisticated and optimize mem usage, you could use malloc and realloc, but you have to deal with freeing the memory when it is no longer needed.
#include <stdio.h>
#include <string.h>
int main ()
{
char str[80];
strcpy (str,"these ");
strcat (str,"strings ");
strcat (str,"are ");
strcat (str,"concatenated.");
puts (str);
return 0;
}
In your case, bit 3 will be encountered as the first set bit and the output string will then contain "THREE", then on the next iteration bit 4 will be detected as set and the output will be appended as "THREE FOUR".
Note: Because this appears to be an academic problem I would like to point out that there exists here the classical case of complexity vs space trade off. My description above was minimum complexity at the expense of space. Meaning, you will have 64 strings with redundancy in many of these strings. For example: TWENTY TWO, THIRTY TWO, FOURTY TWO, FIFTY TWO, and SIXTY TWO, all contain the string "TWO". Space could be optimized by using half the strings: ZERO, ONE, through NINETEEN, then TWENTY, THIRTY, FORTY, FIFTY, SIXTY. However, your indexing logic will be more complicated for bits greater than TWENTY. for bit 21 you will need to concatenate TWENTY and ONE.

Accounting for no existant characters as inputs C

Sorry if the question title is a little bit off, I had no idea what to call it just because it is such a peculiar question. What I am aiming to do is decode an input string encoded using a method I will explain in a bit, into a plain English text.
Encoding is done by choosing an integer nRows between 2 and half the length of the message, e.g. a message of length 11 would allow values of nRows in the range 2 to 5. The message is then written down the columns of a grid, one character in each grid cell, nRows in each column, until all message characters have been used. This may result in the last column being only partially filled. The message is then read out row-wise.
For example if the input message was ALL HAIL CAESAR, and the nRows value was 2, encoding would look like this:
A L H I A S R
L A L C E A #
Where # symbolizes a or blank character in the table, that doesn't actually exist - I have simply added it to explain the next part :)
The actual question I have is decoding these phrases. The code I have written thus far works for a few problems, but once the blank characters (#) become many the code begins to break down, as the code obviously does not register them and the algorithm skips past them.
My code is:
/*
* DeConfabulons.c
* A program to Decode for the Confabulons
*
* August 9th 2015
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
//A simple function confab which given input text encoded using
//the Confabulons encoding scheme, and a number of rows, returns
//the originally encoded phrase.
void deconfab(const char inText[], int nRows, char outText[])
{
int count = 0;
int i = 0;
int len = strlen(inText);
float help = ((float)len/(float)nRows);
int z = 0;
while (z < round(help))
{
while (((int)inText[count] > 0) && (count <= len))
{
outText[i] = inText[count];
i ++;
if (count < (int)help)
{
count = count + round((int)help+0.5);
}
else
{
float helper = count + help;
count = round(helper);
}
}
z ++;
count = z;
}
outText[i] = '\0';
}
Which thus far works for the Caesar example I gave earlier. The encoded form of it was ALHI ASRL ALCEA. The main(void) input I have been provided for that problem was:
char buffer[40] = {'\0'};
deconfab("ALHI ASRL ALCEA", 2, buffer);
printf("%s\n", buffer);
Which correctly outputs:
ALL HAIL CAESAR
However when working with cases with extra "blank" characters such as:
char buffer[60] = {0};
char* s = "Two hnvde eo frgqo .uxti hcjeku mlbparszo y";
deconfab(s, 13, buffer);
printf("%s\n", buffer);
The output should be:
The quick brown fox jumps over the lazy dog.
However my code will return:
Thdefq.the browneorouickmps ov g x julazy
I have concluded that this caused by the blank characters at the end in the last column by running through multiple tests by hand, however no matter what I try the code will not work for every test case. I am allowed to edit the bulk of the function in nearly any way, however any inputs or anything in int main(void) is not allowed to be edited.
I am simply looking for a way to have these blank characters recognized as characters without actually being there (as such) :)
First of all, as far as I see, you don't include those "null" characters in your input - if you did that (I guess) by adding any "dummy" characters, the algorithm would work. The reason it does in the first case is that the 'blank' character is missing at the end of the input - the same place as it's missing in the sentence.
You can try to make a workaround by guessing the length of a message with those dummy characters (I'm not sure how to formulate this) like:
ALHI ASRL ALCEA has 15 characters (15 mod 2 = 1) but ALHI ASRL ALCEA# has 16 characters. Similarly, Two hnvde eo frgqo .uxti hcjeku mlbparszo y has 44 characters (44 mod 13 = 5) so you need quite a lot of the dummy chars to make this work (13-5=8).
There are several ways at this point - you can for instance try to insert the missing blank spaces to align the columns, copy everything into a 2-dimensional array char by char, and then read it line by line, or just determine the (len mod rows) characters from the last column, remove them from the input (requires some fiddling with the classic C string functions so I won't give you the full answer here), read the rest and then append the characters from the last column.
I hope this helps.
There is some mess with index calculation.
At first it is pure discrete transformation. So, it should be implemented using only integer numbers.
The function below does what you need.
void deconfab(const char inText[], int nRows, char outText[])
{
int len = strlen(inText);
int cols = len / nRows;
int rows_with_large_cols = len % nRows;
int count = 0;
int col = 0;
int row = 0;
while (count < len)
{
int idx;
if (row < rows_with_large_cols)
idx = row * (cols + 1) + col;
else
idx = rows_with_large_cols * (cols + 1) +
(row - rows_with_large_cols) * cols + col;
if (idx > len - 1) {
++col;
row = 0;
idx = col;
}
outText[count] = inText[idx];
++row;
++count;
}
outText[count] = '\0';
}
It may be rewritten more nicely. Now it is like a pseudocode to explain the algorithm.
You cannot use the standard str* functions if you are going to handle nulls. You must, instead, work with the data directly and use the *read family of functions to get your data.

Non-recursive combination algorithm to generate distinct character strings

This problem has been irritating me for too long. I need a non-recursive algorithm in C to generate non-distinct character strings. For instance, if a given character string is 26 characters long, and the string is of length 2, then there are 26^2 non-distinct characters.
Please note that these are distinct combinations, aab is not the same as baa or aba. I've searched S.O., and most solutions produce non-distinct combinations. Also, I do not need permutations.
The algorithm can't rely on a libraries. I'm going to translate this C code into cuda where standard C libraries don't work (at least not efficiently).
Before I show you what I started, let me explain an aspect of the program. It is multithreaded on a GPU, so I initialize the beginning string with a few characters, aa in this case. To create a combination, I add one or more characters depending on the desired length.
Here's one method that I have attempted:
int main(void){
//Declarations
char final[12] = {0};
char b[3] = "aa";
char charSet[27] = "abcdefghijklmnopqrstuvwxyz";
int max = 4; //Set for demonstration purposes
int ul = 1;
int k,i;
//This program is multithreaded on a GPU. Each thread is initialized
//to a starting value for the string. In this case, it is aa
//Set final with a starting prefix
int pref = strlen(b);
memcpy(final, b, pref+1);
//Determine the number of non-distinct combinations
for(int j = 0; j < length; j++) ul *= strlen(charSet);
//Start concatenating characters to the current character string
for(k = 0; k < ul; k++)
{
final[pref+1] = charSet[k];
//Do some work with the string
}
...
It should be obvious that this program does nothing useful, accept if I'm only appending one character from charSet.
My professor suggested that I try using a mapping (this isn't homework; I asked him about possible ways to generate distinct combinations without recursion).
His suggestion is similar to what I started above. Using the number of combinations calculated, he suggested to decompose it according to mod 10. However, I realized it wouldn't work.
For example, say I need to append two characters. This gives me 676 combinations using the character set above. If I am on the 523rd combination, the decomposition he demonstrated would yield
523 % 10 = 3
52 % 10 = 2
5 % 10 = 5
It should be obvious that this doesn't work. For one, it yields three characters, and two, if my character set is larger than 10 characters, the mapping ignores those above index 9.
Still, I believe a mapping is key to the solution.
The other method I explored utilized for loops:
//Psuedocode
c = charset;
for(i = 0; i <length(charset); i++){
concat string
for(j = 0; i <length(charset); i++){
concat string
for...
However, this hardcodes the length of the string I want to compute. I could use an if statement with a goto to break it, but I would like to avoid this method.
Any constructive input is appreciated.
Given a string, to find the next possible string in the sequence:
Find the last character in the string which is not the last character in the alphabet.
Replace it with the next character in the alphabet.
Change every character to the right of that character with the first character in the alphabet.
Start with a string which is a repetition of the first character of the alphabet. When step 1 fails (because the string is all the last character of the alphabet) then you're done.
Example: the alphabet is "ajxz".
Start with aaaa.
First iteration: the rightmost character which is not z is the last one. Change it to the next character: aaaj
Second iteration. Ditto. aaax
Third iteration: Again. aaaz
Four iteration: Now the rightmost non-z character is the second last one. Advance it and change all characters to the right to a: aaja
Etc.
First, thanks for everyone's input; it was helpful. Being that I am translating this algorithm into cuda, I need it to be as efficient as possible on a GPU. The methods proposed certainly work, but not necessarily optimal for GPU architecture. I came up with a different solution using modular arithmetic that takes advantage of the base of my character set. Here's an example program, primarily in C with a mix of C++ for output, and it's fairly fast.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
typedef unsigned long long ull;
int main(void){
//Declarations
int init = 2;
char final[12] = {'a', 'a'};
char charSet[27] = "abcdefghijklmnopqrstuvwxyz";
ull max = 2; //Modify as need be
int base = strlen(charSet);
int placeHolder; //Maps to character in charset (result of %)
ull quotient; //Quotient after division by base
ull nComb = 1;
char comb[max+1]; //Array to hold combinations
int c = 0;
ull i,j;
//Compute the number of distinct combinations ((size of charset)^length)
for(j = 0; j < max; j++) nComb *= strlen(charSet);
//Begin computing combinations
for(i = 0; i < nComb; i++){
quotient = i;
for(j = 0; j < max; j++){ //No need to check whether the quotient is zero
placeHolder = quotient % base;
final[init+j] = charSet[placeHolder]; //Copy the indicated character
quotient /= base; //Divide the number by its base to calculate the next character
}
string str(final);
c++;
//Print combinations
cout << final << "\n";
}
cout << "\n\n" << c << " combinations calculated";
getchar();
}

generate a random number of length 25

eg: 1589745896214758962147852.
This is a question I have been slogging out for a while now.
What are the possible ways?
What is the best practice?
You could just call the random number generator 25 times for each digit - simple if you want this as a string.
If you don't have a random number function available there is a simple to implement one.
http://xkcd.com/221/
This is a nice question...
You can use OpennSsl BIGNUM.
This is a simple fatorial example.
#include <stdio.h>
#include <openssl/bn.h>
int main(int argc, char **argv)
{
BIGNUM *fat;
BN_ULONG a, f;
char *resp;
int i;
fat = BN_new();
for (i = 1; i < argc; i++) {
f = atoll(argv[i]);
BN_dec2bn(&fat, "1");
for (a = 2; a <= f; a++) {
BN_mul_word(fat, a);
}
resp = BN_bn2dec(fat);
printf("Fatorial of %s = %s\n", argv[i], resp);
}
return 0;
}
I just dicovered a better example:
#include <stdio.h>
#include <openssl/bn.h>
int main(int argc, char **argv)
{
BIGNUM *fat;
char *resp = NULL;
fat = BN_new();
BN_generate_prime(fat, 80, 1, NULL, NULL, NULL, NULL);
resp = BN_bn2dec(fat);
printf("Big Random Value: %s\n", resp);
}
;)
You will have to deal with a string for saving your number.
Because the signed long long min is -9223372036854775808 and max is 9223372036854775807.
1589745896214758962147852 is much more long.
Your problem is ill defined (at time of writing).
If you need exactly 25 digits then you can simply iterate 25 times getting a random number from 0 to 9 and compiling them into a string of digit characters.
If it must be a 25 digit number (i.e. 1025 <= r <= 1026-1) rather than 25 random digits then the first digit must >= 1 (no leading zeroes).
If you require these digits to represent an integer value, upon which you may perform arithmetic operations, rather than a string of digits, then you will be out of luck with C's built-in data types on any likely platform since the value will require at least 85 bits (1025/log(2)).
You can build a 85 bit representation by concatenating the bits returned from a standard random number generator into a byte array If using the standard C library rand() function check your implementation's RAND_MAX value; some implementations only generate 16 bits, so some care is needed to concatenate them since it may not be a whole word of random bits. However to arithmetically manipulate such a number you will have to create arithmetic functions to do that too (or use a "bignum" library).

Resources