is there any method to compute a one way hash in C programming, which returns the array of bytes for the resulting hash value..
Thanks..
You could use a Lib for that. For example libgcrypt.
Take a look here. That is almost the same question that you askt here.
For the libgcrypt11-dev package (gcrypt.h)
#include <gcrypt.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv){
/* Test for arg string */
if ( argc < 2 ){
fprintf( stderr, "Usage: %s <string>\n", argv[0] );
exit( 1 );
}
/* Length of message to encrypt */
int msg_len = strlen( argv[1] );
/* Length of resulting sha1 hash - gcry_md_get_algo_dlen
* returns digest lenght for an algo */
int hash_len = gcry_md_get_algo_dlen( GCRY_MD_SHA1 );
/* output sha1 hash - this will be binary data */
unsigned char hash[ hash_len ];
/* output sha1 hash - converted to hex representation
* 2 hex digits for every byte + 1 for trailing \0 */
char *out = (char *) malloc( sizeof(char) * ((hash_len*2)+1) );
char *p = out;
/* calculate the SHA1 digest. This is a bit of a shortcut function
* most gcrypt operations require the creation of a handle, etc. */
gcry_md_hash_buffer( GCRY_MD_SHA1, hash, argv[1], msg_len );
/* Convert each byte to its 2 digit ascii
* hex representation and place in out */
int i;
for ( i = 0; i < hash_len; i++, p += 2 ) {
snprintf ( p, 3, "%02x", hash[i] );
}
printf( "%s\n", out );
free( out );
}
Related
There is the CommandLineToArgvW() function, which is CommandLineToArgv + W, where this W means wide char (wchar_t in C/C++). But the CommandLineToArgvA() function that should exist, such as GetCommandLineW() and GetCommandLineA(), does not exist, apparently.
char:
int argv;
char **argv = CommandLineToArgvA(GetCommandLineA(), &argc);
wide char:
int argv;
wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
Well, I searched every corner of the Internet for the term CommandLineToArgvA() and the most I found was this function in Linux Wine... I want to know, does this function exist, and if yes, is it normal that it is "hidden"? Otherwise, does it really not exist?
edit: The question was whether there was the CommandLineToArgvA function in the Windows API, however, it does not exist (comment by Remy Lebeau). The answer I checked as correct is the one that best explains how to use the existing CommandLineToArgvW function and turn the wchar_t into char, which will provide the same result that would be provided with the CommandLineToArgvA function if it existed.
I don’t think you should try parsing your own command-line string. Windows does it one way. Trying to write duplicate code to do the same thing is the Wrong Thing™ to do.
Just get the command-line, then use the Window facilities to convert it to UTF-8.
#include <stdlib.h>
#include <windows.h>
#include <shellapi.h>
#pragma comment(lib, "Shell32")
void get_command_line_args( int * argc, char *** argv )
{
// Get the command line arguments as wchar_t strings
wchar_t ** wargv = CommandLineToArgvW( GetCommandLineW(), argc );
if (!wargv) { *argc = 0; *argv = NULL; return; }
// Count the number of bytes necessary to store the UTF-8 versions of those strings
int n = 0;
for (int i = 0; i < *argc; i++)
n += WideCharToMultiByte( CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL ) + 1;
// Allocate the argv[] array + all the UTF-8 strings
*argv = malloc( (*argc + 1) * sizeof(char *) + n );
if (!*argv) { *argc = 0; return; }
// Convert all wargv[] --> argv[]
char * arg = (char *)&((*argv)[*argc + 1]);
for (int i = 0; i < *argc; i++)
{
(*argv)[i] = arg;
arg += WideCharToMultiByte( CP_UTF8, 0, wargv[i], -1, arg, n, NULL, NULL ) + 1;
}
(*argv)[*argc] = NULL;
}
Obtains an argv just like the one main() gets, with a final NULL element
and writeable and all.
Interface is easy enough. Don’t forget to free() the result when you are done with it. Example usage:
#include <stdio.h>
#include <stdlib.h>
void f(void)
{
int argc;
char ** argv;
get_command_line_args( &argc, &argv );
for (int n = 0; n < argc; n++)
printf( " %d : %s\n", n, argv[n] );
free( argv );
}
int main(void)
{
f();
}
Enjoy!
I'm new to C++, so this should be a fairly basic question.
Assume I have bunny.voxel.ply file. This file is written out in binary, with the first 4 bytes corresponding to the (integer) sampling resolution, res, and the next 4 x res x res x res bytes corresponding to the (single precision) floating point values.
I want to read these values into 3D array voxel. My current code:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fp = fopen( "bunny.voxel.ply" , "rb" );
if (fp==NULL) {fputs ("File error",stderr); exit (1);}
int res;
fread( &res , 1 , sizeof(int) , fp );
float *voxel = new float[res*res*res];
fread(voxel , res * res * res , sizeof(float) , fp );
fclose( fp );
std::cout << "Hello, World!" << std::endl;
return 0;
}
seems to only read the last value.
Any suggestions on how I can modify this read all values?
The Parameters of fread are
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
Thus you probably should exchange the order of your 2nd and 3rd parameter:
int count = res*res*res;
float *voxel = new float[count];
fread(voxel, sizeof(float), count, fp);
By accident the last value was in the correct memory position so that you could identify it.
I'm compiling ZLIB directly into the executable with is being compiled on VS2010 - 64-bit and this simple program always hangs, any ideas? More info below:
Call Stack:
zlibtest.exe!inflate(z_stream_s * strm, int flush) Line 607
zlibtest.exe!uncompress(unsigned char * dest, unsigned long * destLen, const unsigned char * source, unsigned long sourceLen) Line 44
zlibtest.exe!main(int argc, char * * argv) Line 137
It hangs here:
for (;;)
switch (state->mode) {
case HEAD:
if (state->wrap == 0) {
state->mode = TYPEDO;
break;
}
**NEEDBITS(16);**
Program:
#include "zlib.h"
int main( int argc, char * argv[] )
{
char * buffer = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
ULONG buffer_size = strlen( buffer ) + 1;
ULONG compressed_size = compressBound( buffer_size );
BYTE * compressed_buffer = new BYTE[ compressed_size ];
if ( Z_OK != compress2( compressed_buffer, &compressed_size, ( Bytef * ) buffer, buffer_size, Z_DEFAULT_COMPRESSION ) )
printf( "Failed to compress." );
ULONG uncompressed_size = buffer_size;
BYTE * uncompressed_buffer = new BYTE[ uncompressed_size ];
if ( Z_OK != uncompress( uncompressed_buffer, &uncompressed_size, compressed_buffer, compressed_size ) )
printf( "Failed to uncompress" );
printf( "Press <ENTER> to exit..." );
std::cin.ignore();
}
Can anyone Provide a Simple Example to Read and Write in the Unicode File a Unicode Character ?
try http://utfcpp.sourceforge.net/. the link has an introductory example to read a utf8 file, line by line.
On linux I use the iconv (link) library which is very standard. An overly simple program is:
#include <stdio.h>
#include <stdlib.h>
#include <iconv.h>
#define BUF_SZ 1024
int main( int argc, char* argv[] )
{
char bin[BUF_SZ];
char bout[BUF_SZ];
char* inp;
char* outp;
ssize_t bytes_in;
size_t bytes_out;
size_t conv_res;
if( argc != 3 )
{
fprintf( stderr, "usage: convert from to\n" );
return 1;
}
iconv_t conv = iconv_open( argv[2], argv[1] );
if( conv == (iconv_t)(-1) )
{
fprintf( stderr, "Cannot conver from %s to %s\n", argv[1], argv[2] );
return 1;
}
bytes_in = read( 0, bin, BUF_SZ );
{
bytes_out = BUF_SZ;
inp = bin;
outp = bout;
conv_res = iconv( conv, &inp, &bytes_in, &outp, &bytes_out );
if( conv_res >= 0 )
{
write( 1, bout, (size_t)(BUF_SZ) - bytes_out );
}
}
iconv_close( conv );
return 0;
}
This is overly simple to demonstrate the conversion. In the real world you would normally have two nested loops:
One reading input, so handle when its more than BUF_SZ
One converting input to output. Remember if you're converting from ascii to UTF-32LE you will end up with each iunput byte being 4 bytes of output. So the inner loop would handle this by examining conv_res and then checking errno.
In case you're using Windows.
Use fgetws http://msdn.microsoft.com/en-us/library/c37dh6kf(VS.71).aspx to read
and fputws http://msdn.microsoft.com/en-us/library/t33ya8ky(VS.71).aspx to write.
The example code are in the provided links.
I am having trouble converting strings from utf8 to gb2312. My convert function is below
void convert(const char *from_charset,const char *to_charset, char *inptr, char *outptr)
{
size_t inleft = strlen(inptr);
size_t outleft = inleft;
iconv_t cd; /* conversion descriptor */
if ((cd = iconv_open(to_charset, from_charset)) == (iconv_t)(-1))
{
fprintf(stderr, "Cannot open converter from %s to %s\n", from_charset, to_charset);
exit(8);
}
/* return code of iconv() */
int rc = iconv(cd, &inptr, &inleft, &outptr, &outleft);
if (rc == -1)
{
fprintf(stderr, "Error in converting characters\n");
if(errno == E2BIG)
printf("errno == E2BIG\n");
if(errno == EILSEQ)
printf("errno == EILSEQ\n");
if(errno == EINVAL)
printf("errno == EINVAL\n");
iconv_close(cd);
exit(8);
}
iconv_close(cd);
}
This is an example of how I used it:
int len = 1000;
char *result = new char[len];
convert("UTF-8", "GB2312", some_string, result);
edit: I most of the time get a E2BIG error.
outleft should be the size of the output buffer (e.g. 1000 bytes), not the size of the incoming string.
When converting, the string length usually changes in the process and you cannot know how long it is going to be until afterwards. E2BIG means that the output buffer wasn't large enough, in which case you need to give it more output buffer space (notice that it has already converted some of the data and adjusted the four variables passed to it accordingly).
As others have noted, E2BIG means that the output buffer wasn't large enough for the conversion and you were using the wrong value for outleft.
But I've also noticed some other possible problems with your function. Namely, with the way your function works, your caller has no way of knowing how many bytes are in the output string. Your convert() function neither nul-terminates the output buffer nor does it have a means of telling its caller the number of bytes it wrote to outptr.
If you want to deal with nul-terminates strings (and it appears that's what you want to do since your input string is nul-terminated), you might find the following approach to be much better:
char *
convert (const char *from_charset, const char *to_charset, const char *input)
{
size_t inleft, outleft, converted = 0;
char *output, *outbuf, *tmp;
const char *inbuf;
size_t outlen;
iconv_t cd;
if ((cd = iconv_open (to_charset, from_charset)) == (iconv_t) -1)
return NULL;
inleft = strlen (input);
inbuf = input;
/* we'll start off allocating an output buffer which is the same size
* as our input buffer. */
outlen = inleft;
/* we allocate 4 bytes more than what we need for nul-termination... */
if (!(output = malloc (outlen + 4))) {
iconv_close (cd);
return NULL;
}
do {
errno = 0;
outbuf = output + converted;
outleft = outlen - converted;
converted = iconv (cd, (char **) &inbuf, &inleft, &outbuf, &outleft);
if (converted != (size_t) -1 || errno == EINVAL) {
/*
* EINVAL An incomplete multibyte sequence has been encoun-
* tered in the input.
*
* We'll just truncate it and ignore it.
*/
break;
}
if (errno != E2BIG) {
/*
* EILSEQ An invalid multibyte sequence has been encountered
* in the input.
*
* Bad input, we can't really recover from this.
*/
iconv_close (cd);
free (output);
return NULL;
}
/*
* E2BIG There is not sufficient room at *outbuf.
*
* We just need to grow our outbuffer and try again.
*/
converted = outbuf - out;
outlen += inleft * 2 + 8;
if (!(tmp = realloc (output, outlen + 4))) {
iconv_close (cd);
free (output);
return NULL;
}
output = tmp;
outbuf = output + converted;
} while (1);
/* flush the iconv conversion */
iconv (cd, NULL, NULL, &outbuf, &outleft);
iconv_close (cd);
/* Note: not all charsets can be nul-terminated with a single
* nul byte. UCS2, for example, needs 2 nul bytes and UCS4
* needs 4. I hope that 4 nul bytes is enough to terminate all
* multibyte charsets? */
/* nul-terminate the string */
memset (outbuf, 0, 4);
return output;
}