I would like to hash a simple string using MD5 in Xcode c++. I searched a lot but I couldn't find a tutorial. I have to #import <CommonCrypto/CommonDigest.h>. Is that all? How can I call MD5 after that?
I have found this code but it gives me an error. How will I get my hashed value is it updated in the string variable?
unsigned char digest[16];
const char* string = "Hello World";
struct MD5Context context; **(error: variable has incomplete type
MD5Init(&context);
MD5Update(&context, string, strlen(string));
MD5Final(digest, &context);
I'm just using a simple command line application no headers inside just the basic main.cpp.
I really appreciate any help!!!!
You're using the wrong API. I'm not sure where you're getting those from (they look like OpenSSL calls), but it should look like this:
#include <stdio.h>
#include <string.h>
#include <CommonCrypto/CommonDigest.h>
int main()
{
unsigned char digest[CC_MD5_DIGEST_LENGTH];
const char string[] = "Hello World";
CC_MD5_CTX context;
CC_MD5_Init(&context);
CC_MD5_Update(&context, string, (CC_LONG)strlen(string));
CC_MD5_Final(digest, &context);
for (size_t i=0; i<CC_MD5_DIGEST_LENGTH; ++i)
printf("%.2x", digest[i]);
fputc('\n', stdout);
return 0;
}
Output
b10a8db164e0754105b7a99be72e3fe5
Validated here.
There is a one-shot version:
#include <CommonCrypto/CommonDigest.h>
unsigned char digest[16];
const char* string = "Hello World";
CC_MD5(string, (CC_LONG)strlen(string), digest);
You will need to include the Security.framework (or at lease the applicable library file).
Related
I'm trying to create a folder with a custom name for each user that will logged in but it doesn't work. Can you please help me? I'm a beginner and it's quite difficult.
#include <iostream>
#include <direct.h>
using namespace std;
int main() {
string user = "alex";
_mkdir("D:\\Programe\\VS\\ATM\\Fisiere\\" + user);
return 0;
}
I was trying to make the folder in the same way I make the files, but it doesn't work.
_mkdir is an older function which takes a C string as it's parameter. So you have to convert the std::string that you have into a C string. You can do that with the c_str method. Like this
_mkdir(("D:\\Programe\\VS\\ATM\\Fisiere\\" + user).c_str());
This code creates a std::string by appending the path with the user string and then calls c_str on that string and then passes the result of that to _mkdir.
I am updating my "C++" knowledge to the latest version using Unicode Strings etc..
Can someone please just confirm than creating a String within a function and Returning it is Valid? and it will retain the actual String data.
Below is a cut-down "nonsense" function, but is this "legal" and "safe" regarding creating & returning the String.? My testing suggests it is, but I would not notice if some memory was freed but not cleared.
#include <vcl.h>
#include <wchar.h>
#include <stdio.h>
UnicodeString MyUTFToUnicode (WideChar *In);
int _tmain(int argc, _TCHAR* argv[])
{
UnicodeString Test;
WideChar In[] = L"My Wide String";
Test = MyUTFToUnicode(In);
wprintf(L"%s\n",Test.c_str());
return 0;
}
UnicodeString MyUTFToUnicode (WideChar *In)
{
WideChar wc[500];
UnicodeString Out;
swprintf(wc,500,L"Hello This is The Input String : %s", In);
Out = wc;
return Out;
}
Regards
I can't figure this one out. I have a c++ Application that works in Debug mode exactly as expected:
#include "stdafx.h"
#include <string>
#include <Windows.h>
#include <iostream>
using namespace std;
void truncateServer(std::string inString);
int _tmain(int argc, char *argv[])
{
char* server = argv[1];
truncateServer(server);
}
void truncateServer(std::string inString)
{
std::string server = "";
int whackCount = 0;
for (unsigned int i = 0; i < inString.length(); i++)
{
char c = inString[i];
if (whackCount < 3)
{
if (c == '\\') whackCount++;
else
server += c;
}
}
cout << server;
}
For example if I call the server I want via its UNC path \\serverName\Share\ in the debug it gives me exactly what I want: servername
However, if I use the release build I get nothing:
I deleted the release output folder, but the issue is exactly the same. I can only assume there is some other difference between the release and build applications that is exposing a major issue with my code? Or another difference between the outputs I need to account for.
What do I need to do to get the expected output?
It looks like your Debug build is set as Ansi and your release build as Unicode.
The _tmain declaration is a Visual Studio specific macro which changes the entry point of your application depending on the used charset.
For ANSI it maps to int main(int argc, char *argv[]) .
For Unicode it maps to int wmain(int argc, wchar_t *argv[]).
By using the char type as parameter to _tmain, you cause the compiler to use the wrong type when using an Unicode build, and so end up with a '\0' character as first byte, which std::string can't handle.
In your case, I recommend sticking to int main(int argc, char *argv[]) as it will work in all cases, especially with std::string which use chars.
Also, it is more portable across compilers and operating systems.
I am trying to include a function from another file inside a "main" file. I'm following this paradigm:
http://www.learncpp.com/cpp-tutorial/18-programs-with-multiple-files/
Here is my main file, digispark.cpp:
#include <iostream>
using namespace std;
int send(int argc, char **argv);
int main()
{
char* on;
*on = '1';
char* off;
*off = '0';
send(1,&on);
return 0;
}
And here is my send.cpp:
#include <stdio.h>
#include <iostream>
#include <string.h>
#if defined WIN
#include <lusb0_usb.h> // this is libusb, see http://libusb.sourceforge.net/
#else
#include <usb.h> // this is libusb, see http://libusb.sourceforge.net/
#endif
// I've simplified the contents of send for my debugging and your aid, but the
// complicated arguments are a part of the function that will eventually need
// to be here.
int send (int argc, char **argv)
{
std::cout << "Hello";
return 0;
}
I'm compiling on Ubuntu 12.10 using the g++ compiler like so:
g++ digispark.cpp send.cpp -o digispark
It compiles successfully.
However, when I run the program, "Hello" does not come up. Therefore I don't believe the function is being called at all. What am I doing wrong? Any help would be great! Thanks!
EDIT:
How I dealt with the issue:
int send(int argc, char **argv);
int main()
{
char* on[4];
on[0] = (char*)"send";
on[1] = (char*)"1";
char* off[4];
off[0] = (char*)"send";
off[1] = (char*)"0";
send(2,on);
return 0;
}
For those of you who were confused as to why I insisted doing this, as I said before, the send function was already built to accept the char** argv (or char* argv[]). My point was to try to mimic that in my main function.
It would have been much more difficult to rewrite the function that actually goes in the send function to take a different type of argument than just to send in what it wanted. Thanks everyone!
So if this helps anyone trying something similar feel free to use it!
Your problem is not the one you think it is. It's here:
char* on;
*on = '1';
You declared a char pointer, but did not initialize it. Then you dereferenced it. Bang, you're dead. This is what is known as Undefined Behavior. Once you invoke U.B., anything can happen. If you're lucky, it's a crash. But I guess you weren't lucky this time.
Look, if you want to start storing things in memory, you have to allocate that memory first. The best way, as hetepeperfan said, is to just use std::string and let that class take care of all the allocating/deallocating for you. But if for some reason you think you have to use C-style strings and pointers, then try this:
char on[128]; //or however much room you think you'll need. Don't know? Maybe you shoulda used std::string ...
*on = '1';
*(on+1) = '\0'; //if you're using C-strings, better null terminate.
char off[128];
*off = '0';
*(off+1) = '\0';
send(1,&on);
ok I think you try to do something like the following, I tried to make it a bit more in the Style of C++ and prevent the use of pointers since they should not be necessary in the code that you showed.
digispark.cpp
#include "send.h"
int main (int argc, char** argv){
string on = "1";
string off = "0";
send ( on );
send ( off );
return 0;
}
send.cpp
#include <iostream>
#include <string>
void send( const std::string& s) {
std::cout << s << std::endl;
}
send.h
void send(const std::string& s);
#include "stdafx.h"
#include <string>
#include <windows.h>
using namespace std;
int main()
{
string FilePath = "C:\\Documents and Settings\\whatever";
CreateDirectory(FilePath, NULL);
return 0;
}
Error: error C2664: 'CreateDirectory' : cannot convert parameter 1 from 'const char *' to 'LPCTSTR'
How do I make this conversion?
The next step is to set today's date as a string or char and concatenate it with the filepath. Will this change how I do step 1?
I am terrible at data types and conversions, is there a good explanation for 5 year olds out there?
std::string is a class that holds char-based data. To pass a std::string data to API functions, you have to use its c_str() method to get a char* pointer to the string's actual data.
CreateDirectory() takes a TCHAR* as input. If UNICODE is defined, TCHAR maps to wchar_t, otherwise it maps to char instead. If you need to stick with std::string but do not want to make your code UNICODE-aware, then use CreateDirectoryA() instead, eg:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::string FilePath = "C:\\Documents and Settings\\whatever";
CreateDirectoryA(FilePath.c_str(), NULL);
return 0;
}
To make this code TCHAR-aware, you can do this instead:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::basic_string<TCHAR> FilePath = TEXT("C:\\Documents and Settings\\whatever");
CreateDirectory(FilePath.c_str(), NULL);
return 0;
}
However, Ansi-based OS versions are long dead, everything is Unicode nowadays. TCHAR should not be used in new code anymore:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::wstring FilePath = L"C:\\Documents and Settings\\whatever";
CreateDirectoryW(FilePath.c_str(), NULL);
return 0;
}
If you're not building a Unicode executable, calling c_str() on the std::string will result in a const char* (aka non-Unicode LPCTSTR) that you can pass into CreateDirectory().
The code would look like this:
CreateDirectory(FilePath.c_str(), NULL):
Please note that this will result in a compile error if you're trying to build a Unicode executable.
If you have to append to FilePath I would recommend that you either continue to use std::string or use Microsoft's CString to do the string manipulation as that's less painful that doing it the C way and juggling raw char*. Personally I would use std::string unless you are already in an MFC application that uses CString.