What is this C function doing? - c

I understand that it's going to take in a number and return a character. I understand what each line of code is doing, but I can't really express what it's doing overall in a meaningful way. Any ideas?
int function(uint64_t P1) {
uint64_t L1 = P1;
uint32_t L2 = 1;
while (L1 > 15) {
L2 = (uint64_t)L2 << 4;
L1 = L1 >> 4;
}
uint32_t L3 = 0;
while (L2 != 0) {
L1 = P1;
uint32_t L4 = 0;
L4 = L1 % L2;
uint64_t L5 = (uint64_t)L4;
sub_function(L1 / L2);
L3++;
P1 = L5;
L2 = (uint64_t)L2 >> 4;
}
L1 = L3;
return L1;
}
void sub_function(uint64_t P1) {
if (P1 <= 9) {
printf("%c", P1 + 48);
} else {
printf("%c", P1 + 55);
}
}

This code accepts a decimal value and prints the hexadecimal representation.
Try it out yourself
In C we can use the %x (%X) format specifier flag to printf to do it for us:
printf("%X", 16); // 10
printf("\n");
printf("%X", 42); // 2A
If you're using a C++ compiler, we can instead use the std::hex stream manipulation flag on iostream to achieve the same result:
std::cout << std::hex << 16 << std::endl; // 10
std::cout << std::hex << 42 << std::endl; // 2a

Related

Simplification of For Loop with different inputs

I would like to know if anyone of you has an idea of how I could choose the values in order to not to have the for loop repeated for every input. Thank you in advance.
#include <iostream>
using namespace std;
int main()
{
int a, b, c, d, e, f, g, h, i;
std::cout << "Please enter a number from 1 to 8: ";
std::cin >> i;
std::cout << "The value you entered is " << i;
std::cout << "\n";
if (0 <= i <= 8) {
if (i == 8) {
for (a = 1; a <= 8; a++)
{
std::cout << "\n";
for (c = 7; c >= a; c--) {
std::cout << " ";
}
for (b = 1; b <= a; b++) {
std::cout << "#";
}
}
}
else if (i == 7) {
for (a = 2; a <= 8; a++)
{
std::cout << "\n";
for (c = 7; c >= a; c--) {
std::cout << " ";
}
for (b = 1; b <= a; b++) {
std::cout << "#";
}
}
}
else if (i == 2) {
for (a = 7; a <= 8; a++)
{
std::cout << "\n";
for (c = 7; c >= a; c--) {
std::cout << " ";
}
for (b = 1; b <= a; b++) {
std::cout << "#";
}
}
}
}
return 0;
}
Here I would like to put all the loops together, meaning I dont have to type in the same loop for every integer
First, let me point out that this does not mean what you think it does:
if (0 <= i <= 8)
In C++, you need to write it like this:
if (0 <= i && i <= 8)
Now on to your loops. You wrote out three loops, for the cases where i is 8, 7, and 2, but I assume you also wants loops for the other acceptable values of i.
The only differences between your loops are what i must be and what a starts at:
i
initial a
8
1
7
2
2
7
What is the relationship between i and the initial a here? I notice that i + a == 9 in all three cases. So we can compute a = 9 - i.
if (0 <= i && i <= 8) {
for (a = 9 - i; a <= 8; a++) {
std::cout << "\n";
for (c = 7; c >= a; c--) {
std::cout << " ";
}
for (b = 1; b <= a; b++) {
std::cout << "#";
}
}
}

Base64 Encoding Padding in C

I am writting a base64 encoder and decoder and have it almost completly functional, I just need to be able to pad the encoded data with equal signs if the number of input bytes does not round out to a multiple of 3. I am relativly new to C and am not sure how I would detect the number of bytes or pad the output accordingly. This is what I have so far
void encode(char* src, char* dest) {
char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char first = (src[0] >> 2);
unsigned char second = (src[0] << 4) | (src[1] >> 4);
second = (second << 2);
second = (second >> 2);
unsigned char third = (src[1] << 2) | (src[2] >> 6);
third = (third << 2);
third = (third >> 2);
unsigned char fourth = (src[2]);
fourth = (fourth << 2);
fourth = (fourth >> 2);
dest[0] = base64[first];
dest[1] = base64[second];
dest[2] = base64[third];
dest[3] = base64[fourth];
}
And my decoder method...
void decode(char* src, char* dest) {
char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int i;
int j;
int index;
for(i = 0; i < 4; i++) {
index = 0;
for(j = 0; j < 64; j++) {
if (src[i] == base64[j]) {
src[i] = index;
} else {
index++;
}
}
}
char first = (src[0] << 2) | (src[1] >> 4);
char second = (src[1] << 4) | (src[2] >> 2);
char third = (src[2] << 6) | (src[3]);
dest[0] = first;
dest[1] = second;
dest[2] = third;
}
If this is not enough and I need to also provide the rest of my code I can do so.

Send a variable to a function and modify this variable in C

I have the following vars:
char seed[NBITS + 1], x0[NBITS + 1], y0[NBITS + 1], z0[NBITS + 1], dT0[NBITS + 1];
And i want to change it values on this function:
void lfsr(char *bin, char *output)
{
//bits significativos para fazer o xor NBITS -> NBITS,126,101,99;
int bits[4];
int bit;
if(bin[0] == '0')
bits[0] = 0;
else if(bin[0] == '1')
bits[0] = 1;
if(bin[2] == '0')
bits[1] = 0;
else if(bin[2] == '1')
bits[1] = 1;
if(bin[21] == '0')
bits[2] = 0;
else if(bin[21] == '1')
bits[2] = 1;
if(bin[19] == '0')
bits[3] = 0;
else if(bin[19] == '1')
bits[3] = 1;
bit = bits[0] ^ bits[1] ^ bits[2] ^ bits[3] ^ 1;
//reconstruir o vector de char depois do lfsr
for(int i = 127; i >= 1; i--)
{
bin[i] = bin[i - 1];
}
bin[0] = (char)(48 + bit);
output = bin;
}
The way that I put the value in y0 from x is, for example, calling the lfsr functions like this:
lfsr(x0, y0);
What am I doing wrong?
I have to do 3 Fibonacci Linear Feedback Shift Register starting from x0.
x0 = 10101010101010
y0 = lfsr(101010101010)
z0 = lfsr(y0)
dT0 = lfsr(z0);
The results are good, but when I do the above code the value of x0 will be the same as dT0 if i use pointers.
Can anyone help me?
Thanks. Cumps!
Consider the following:
The numbers correspond to the taps. The bits are actually 15..0, left to right. The following is my implementation of the Fibonacci Linear Feedback Shift Register:
#include <stdio.h>
uint16_t fibLfsr(const uint16_t num)
{
uint16_t tempNum;
tempNum = (num) ^ (num >> 2) ^ (num >> 3) ^ (num >> 5);
tempNum = (tempNum & 0x1) << 15;
tempNum = (tempNum | (num >> 1));
return tempNum;
}
int main(void)
{
uint16_t testNum = 0xACE1;
printf("%#X\n", testNum);
testNum = fibLfsr(testNum);
printf("%#X\n", testNum);
return 0;
}
I'm not quite sure why you're using strings and converting them to binary. If this is necessary, you'll need some of the standard library APIs in stdlib and string to convert the string to an uint16_t before calling fibLfsr() and back to a string afterwards.

Reading raw audio files

How do you
Read a 16 bit stereo raw audio file in binary mode
Convert it's values to integer for right and for left.
Save those integers back to a new 16 bit stereo raw audio file.
The final two files should be the same, with my code, they are not. Why?
My code:
char ergebnis[80];
sprintf(ergebnis,"%s.neu.raw",Datei);
FILE* ausgabe = fopen(ergebnis, "wb");
FILE* f = fopen(Datei, "rb");
if (f == NULL)
return;
int i = -1;
int r1 = 0;
int r2 = 0;
int l1 = 0;
int l2 = 0;
int l = 0;
int r = 0;
while((getc(f))!=EOF)
{
i++;
if (i == 0)
r1 = (unsigned)fgetc(f);
if (i == 1)
{
r2 = (unsigned)fgetc(f);
r = r1 | r2 << 8;
}
if (i == 2)
l1 = (unsigned)fgetc(f);
if (i == 3)
{
l2 = (unsigned)fgetc(f);
l = l1 | l2 << 8;
putc(r,ausgabe);
putc(l,ausgabe);
i = -1;
}
}
fclose(f);
fclose(ausgabe);
exit(-1);
EDIT: Solved it with
int wo = 0;
while(wo !=EOF)
{
wo = getc(f);
i++;
if (i == 0)
r1 = (unsigned)wo;
if (i == 1)
{
r2 = (unsigned)wo;
r = (r2<<8)+r1; //r1 | r2 << 8;
}
if (i == 2)
l1 = (unsigned)wo;
if (i == 3)
{
l2 = (unsigned)wo;
l = (l2<<8)+l1; //l1 | l2 << 8;
putc((char) ( r & 0xff),ausgabe);
putc((char) ((r >> 8) & 0xff),ausgabe);
putc((char) ( l & 0xff),ausgabe);
putc((char) ((l >> 8) & 0xff),ausgabe);
i = -1;
}
}
Getc in the while will skip one character.
Also if you have 16bit per channel instead of
putc(r,ausgabe);
putc(l,ausgabe);
do
putc((char) ( r & 0xff),ausgabe);
putc((char) ((r >> 8) & 0xff),ausgabe);
putc((char) ( l & 0xff),ausgabe);
putc((char) ((l >> 8) & 0xff),ausgabe);
Possibly you want a different endianness then just swaplines 1 and 2 and lines 3 and 4

C Concatenate int

I will be the first to admit, I'm a C# guy 100% and C isn't for me. However I have problem.
I need to concatenate 7 with HashUrl(HashInt) and then with HashInt
Any help would be greatly appreciated.
int main(int argc)
{
unsigned int HashInt;
HashInt = HashURL(argc);
// I need to return 7 + CheckHash(HashInt) + HashInt but not ADDING, but concanenating them
return HOWEVERTOGETTHESTRING;
}
I should have specified the usage of this. It's actually going to be used in a students VB6 project.
Private Declare Function main Lib "checksum.dll" (ByVal pStr As String) As Long
Private Sub Command1_Click()
MsgBox main("http://hello.com")
End Sub
The full source for the C library is
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <string.h>
#include <winreg.h>
#include <stdlib.h>
int StrToInt(char *pStr, int Init, int Factor)
{
while (*pStr) {
Init *= Factor;
Init += *pStr++;
}
return Init;
}
int HashURL(char *pStr)
{
unsigned int C1, C2, T1, T2;
C1 = StrToInt(pStr, 0x1505, 0x21);
C2 = StrToInt(pStr, 0, 0x1003F);
C1 >>= 2;
C1 = ((C1 >> 4) & 0x3FFFFC0) | (C1 & 0x3F);
C1 = ((C1 >> 4) & 0x3FFC00) | (C1 & 0x3FF);
C1 = ((C1 >> 4) & 0x3C000) | (C1 & 0x3FFF);
T1 = (C1 & 0x3C0) << 4;
T1 |= C1 & 0x3C;
T1 = (T1 << 2) | (C2 & 0xF0F);
T2 = (C1 & 0xFFFFC000) << 4;
T2 |= C1 & 0x3C00;
T2 = (T2 << 0xA) | (C2 & 0xF0F0000);
return (T1 | T2);
}
char CheckHash(unsigned int HashInt)
{
int Check = 0, Flag = 0;
int Remainder;
do {
Remainder = HashInt % 10;
HashInt /= 10;
if (1 == (Flag % 2) ){
Remainder += Remainder;
Remainder = (Remainder / 10) + (Remainder % 10);
}
Check += Remainder;
Flag ++;
} while( 0 != HashInt);
Check %= 10;
if (0 != Check) {
Check = 10 - Check;
if (1 == (Flag % 2)) {
if (1 == (Check % 2)) {
Check += 9;
}
Check >>= 1;
}
}
Check += 0x30;
return Check;
}
int main(int argc)
{
unsigned int HashInt;
int result;
HashInt = HashURL(argc);
char temp[100];
sprintf(temp, "7%i%j", CheckHash(HashInt), HashInt);
result = atoi(temp);
return result;
}
give " http://www.hello.com" should return 783544359868 but its not
You can use sprintf function to create formatted strings. To concatenate 3 integers into a string you could use something like
sprintf(string, "%d%d%d", int1, int2, int3)
I'm not all that great at C, but how I would solve this problem is to first turn them into character arrays, then concatenate those. Then you could turn the result back into an int:
int main(int argc) {
unsigned int HashInt;
int result;
HashInt = HashURL(argc);
char temp[50];
sprintf(temp, "7%i%i", CheckHash(HashInt), HashInt);
result = atoi(temp);
return result;
}
Note: No guarantees on this working...
For starters, you can look at:
asprintf
Just do man asprintf on a linux system.
Here's a link that has a simple example that you can adapt:
http://www.gnu.org/s/libc/manual/html_node/Dynamic-Output.html

Resources