For loop with specific function - c

I have a small problem with a program I am working on.
My program executes a function on an array. The function only can execute the commands on the first 16 elements of the array.
I now want to make a loop so that the function can work on more than 16 elements of the array. Here's my thought, but it ended up in an infinite loop:
int l = 0;
for (int i=0; i<=size; i+16)
{
for (int j=0; j<=16;j++)
{
FUNCTION(INARRAY; OUTARRAY);
}
}
Next problem is that the function will only walk through 16 Elements of the array and ignore the rest.
What is the best way to make it walk through the next 16 elements and save it in the outbuffer as the following elements?
As I adapt the solution it still does only process through the first 16 elements and then doesn't continue with the next 16.

This:
i + 16
does nothing to change the value of i, so that loop never terminates. That expression just computes the value of i + 16, but the result is thrown away.
To change the value of a variable, use assignment (=) operator, like i = i + 16 or i += 16.

I think I have what you are looking for. You would have to implent it and check it out. Be warned though that this worked if your arrays size is a multiple of 16, otherwise there will be remaining elements paired with already processed elements.
int count16 = 0;
var tempAr[16];
for (int i=0; i<numOfArraysToGoThrough; i++)
{
tempAr[count16]=numOfArrayToGoThrough[i];
if ( count16 == 15)
{
FUNCTION (tempAr, OUTARRAY);
count16=0;
}
else
count16+=1;
}

figured this one out some time ago
here's how it worked for me
for (uint64_t i=0; i<size; i+=16)
{aes_encrypt(tfm, &tempbuffer[i], &inbuffer[i]);}
this does the following
calling aes_encrypt will encrypt the first 16 bytes of data in the array,
the for loop then jumps to the 16th entry and performs the encryption again

Related

Swapping elements in Array of Pointers

I have the following array in C (Used random names)
char * inputs[6] = {
"Kangaroo my shoe", "Fly high dragonfly",
"Philosophical Monkey", "Jumping Ape",
"Fearful lemurs", "Tall Giraffes"
};
The goal is to swap the first element by the next. As in to do this
char * inputs[6] = {
"Fly high dragonfly", "Kangaroo my shoe",
"Jumping Ape", "Philosophical Monkey",
"Tall Giraffes", "Fearful lemurs"
};
I have tried the following and some more.
ArrSwap(char *Arr[]){
int i;
for(i=0;i<6;i++){
void*temp = Arr[i];
Arr[i]=Arr[i+1];
Arr[i+1] = temp;
}
}
Thanks in advance! I've spent some hours trying to figure this out, each time I do it it ends up with a messed up order or not swapping any elements expect for the first and last.
There are two problems in your code -
In function ArrSwap() you are looping over index 0 to 5. So, when i becomes 5, Arr[i+1] points to Arr[6] which leads to read from a memory past your array bounds. Which is undefined behavior.
Secondly, if I get your requirement correctly, you want to swap the first and second elements swapped, then third and fourth and so on. So, your code has a logic error. In that case, in ArrSwap() the loop needs to increment by 2 instead of 1.
So the code may look like this after both issues are addressed -
void ArrSwap(char *Arr[]){
int i;
for(i=0; i<5; i+=2) {
char *temp = Arr[i];
Arr[i]=Arr[i+1];
Arr[i+1] = temp;
}
}
Notice there are following changes done in the ArrSwap() function -
The loop test condition changed from i < 6 to i < 5 (the reason mentioned in point 1 above). As ikegami mentioned, best practice would be to pass the array size as an argument (say n) and use n - 1 in loop condition.
The logic is fixed (as mentioned in point 2 above)
For swap, use char * instead of void * (The type of elements in Arr is char *)
The return type of ArrSwap() is mentioned as void. With void it is clearly conveyed that ArrSwap() will not return anything.
After fix the inputs will be:
{"Fly high dragonfly", "Kangaroo my shoe", "Jumping Ape", "Philosophical Monkey", "Tall Giraffes", "Fearful lemurs"}

Why am I getting this output from printing the contents of an array with only 17 bytes?

I am working through CS50 on edX and have reached the problem where you have to do a checksum for credit card numbers.I am new to programming and even newer to C.
I am collecting the digits in arrays so I can manipulate them.
I have collected every other digit from the original number and multiplied this by two.
When I try to print this collection I get the digits I want initially but then a dash and whole load of other numbers - I have no idea where these are coming from?
// establishing another array to collect the doubled digits of every other digit from the first array
int doubledDigs[16];
int k = 0;
// building that array, ensuring to split any multi digit products and add them idnividually
for (int i = 0; i<= 15; i += 2, k++)
{
int a = collector[i] * 2;
if (a > 9)
{
for (int c=0; c < 2; c++, k++)
{
int b = a % 10;
doubledDigs[k] = b;
a = floor(a / 10);
}
}
doubledDigs[k] = a;
}
// print doubledDigs to check it is working
for (int i = 0; i <= 15; i++)
{
int b = doubledDigs[i];
printf ("%i", b);
}
printf ("\n");
//add all the doubled digits together
int doubledProduct = 0;
for (int i=0; i <= 15; i++)
{
doubledProduct += doubledDigs[i];
}
//print product to check
printf("%i\n", doubledProduct);
So if input 1234567890123 as my card number I get 62810410010620-74895702432659
-748924334
as an output.The first 14 digits are correct and the ones that I want - but where are all these other numbers coming from?
You're getting this output because of one of two things: either you're accessing your collector array out of its bounds, or you're failing to initialize the last few members of that array, resulting in garbage data being accessed.
Your algorithm assumes that collector and doubledDigs have the same number of members, but since your code doesn't include the part where you declare that array, it's unclear if that is true or not.
Assuming they are the same size, if you're filling collector with the input "1234567890123", then you're leaving 3 uninitialized members. In C, if you do not explicitly set the value of a variable or array member, its initial value is equal to whatever happens to be in memory at that particular location. For a signed int, that can be anywhere between 2,147,483,647 and -2,147,483,648.
To guard against this, the first thing you may want to do is zero-initialize your array using int collector[16] = {0};.
That only fixes things in the case that collector and doubledDigs are supposed to be the same size. If it's intended that collector has 14 members and doubledDigs has 16, for instance, you will have to revisit your loop logic. In that example, in the last 2 iterations of the loop, you will attempt access the 15th and 16th members of collector, which don't exist. C will not stop you from doing this, but the result is undefined behavior at best.

Heap sort "visual" tree prints extra zeros

I've learned Heap Sort with a visual representation of it with the infamous tree diagram (here), so I set out to find a way to print one out and I've progressed very well so far. My only problem seems to be that if, there aren't any more values to fill up on the line, my program seems to print zeros for some reason.
I'm certain it's probably an error in my code, or an extra line that needs to be added but I'm also looking for advice if this was the best approach. Code below.
#include <stdio.h>
int HeapArray[] = {165, 245, 398, 426, 575, 661, 775, 895, 901, 1028, 1184, 1283, 1350,1427, 1598, 1698};
int main()
{
int i = 0, numL = 1;
int j, k;
for(k = 0; k < 6; k++)
{
if(HeapArray[i] == 0)
break;
for(j = 0; j < numL;j++)
{
printf("%d ", HeapArray[i]);
i++;
}
printf("\n");
numL *= 2;
}
return 0;
}
Things to mention:
In the other most for-loop, I've using the value 6 as the maximum lines to print, however the program stops printing on the line with the last array values in it.
I haven't implemented any alignment to make the diagram 100% accurate since it seemed easy enough to leave for last (i.e. no extra code to confuse me).
Your index i is probably going past the bound of the array
You have 16 elements, so the first time you print 1, then you print 2, then 3, etc
In total you would print 1 + 2 + 4 + 8 = 15 on the fourth line.
When you get to the last line (fifth line), you only have one element to print. However, your inner loop goes from 0 to 16, going past the bounds of the array (and so it prints 0s)
You should add a check in the inner loop to make sure you still have enough elements.
Note that I also highly recommend you actually add a 0 element to the end of the array, so you are not relying on memory outside of its bounds

How does 0+= VARIABLE result in VARIABLE+1?

I ran into a strange bug when updating a counter that is used to calculate the variable for a switch statement.
int iCount was assigned zero outside of the loop, and it is the counter used for the while loop.
To update the counter inside the loop, I wrote iCount+= packedCount, where packedCount was 7 in this case. In the debugger, however, 0+=packedCount resulted in packedCount+1, which was 8. That resulted in an array slot remaining unfilled throughout the loop.
When I changed the line to icount= packedCount+iCount, the proper value was returned.
So, is this behavior unique to C, as I do this regularly in Java with no strange effects.
EDIT- Code snippet added
#define SKIP 8
#define PACKED 7
int iCount;
iCount=0;
while (iCount < characters-1){
for (packedCount=iCount; packedCount< iCount+PACKED; packedCount++){
//ASCII compressor logic goes here
}
//iCount+= packedCount; //this produces 8 for 0+packedCount
//this works
iCount= iCount+packedCount; //skip the next byte in array, since it was already packed
}
As far as the compilers are concerned
iCount += packedCount;
iCount = iCount + packedCount;
are identical. If they're producing different results, then something in your code is causing iCount to get trashed - a bad pointer reference, perhaps.
Try this, and other variations you can think of:
#define SKIP 8
#define PACKED 7
int iCount;
iCount=0;
while (iCount < characters-1){
for (packedCount=iCount; packedCount< iCount+PACKED; packedCount++){
//ASCII compressor logic goes here
}
printf("iCount after the inner loop: %d\n", iCount); /* DEBUG */
printf("packedCount after the inner loop: %d\n", packedCount); /* DEBUG */
//iCount+= packedCount; //this produces 8 for 0+packedCount
//this works
iCount= iCount+packedCount; //skip the next byte in array, since it was already packed
printf("iCount after update: %d\n", iCount); /* DEBUG */
}

Need help with brute force code for crypt(3)

I am trying to develop a program in C that will "crack" the crypt(3) encryption used by UNIX.
The most naive way to do it is brute forcing I guess. I thought I should create an array containing all the symbols a password can have and then get all possible permutations of them and store them in a two-dimensional array (where all the 1 character passwords get's saved in the first row etc.) through for loops. Is there any better way to do this? It's pretty messy with the loops.
Assuming only 62 different characters can be used, storing all the possible 8 character passwords requires 62^8=198 Terabytes.
To anwser you loop question, here is some code to loop over all the possible passwords of a given len, using the characters for a given set:
int len = 3;
char letters[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int nbletters = sizeof(letters)-1;
int main() {
int i, entry[len];
for(i=0 ; i<len ; i++) entry[i] = 0;
do {
for(i=0 ; i<len ; i++) putchar(letters[entry[i]]);
putchar('\n');
for(i=0 ; i<len && ++entry[i] == nbletters; i++) entry[i] = 0;
} while(i<len);
}
The main part is the last for loop. In most cases, it only increments the first entry, and stops there, as this entry has not reached nbletters. If the entry reaches nbletter, it means it has to return to zero, and it's the turn of the next entry to be incremented. It is indeed an unusual loop condition: the loop continues until there is no overflow. The looping only occurs in the worst case: when several entries are on the last element.
Imagine the case where the current word is "zzzc". In turn, each entry is incremented, its overflow is detected, it is reset to 0, and the next entry is considered, until the last entry which does not overflow, to give "000d".
As the commenters on the question point out - you don't have the necessary RAM, and you don't need to store it all.
Covering the permutations in sort sequence is not the most efficient approach to password cracking, although it will ultimately be effective.
An approach to achieving full coverage is to iterate 0 through the number of permutations and encode the value with the size of your character set as a base. This can be scaled to the size of your character set quite easily.
(pseudocode, but you get the idea)
passChars = '[all characters used in this attempt]'
permutationCount = 8^len(passChars) #crypt(3) only uses 8 chars
output = ''
for looper = 0 to permutationCount - 1
localTemp = looper
while localTemp > 0
output += passchars[localTemp%len(passchars)] # % being modulus
localTemp = floor(localTemp/len(passChars))

Resources