How do I convert array<unsigned char> to an unsigned char[]? - c++-cli

In a CLR project I have the output of AesManaged class as a 16 byte array
array<unsigned char>^ result = msEncrypt->ToArray();
However I need to convert this to an array of type unsigned char defined like this
unsigned char buff[16];
EDIT: I did try this but its giving error (no method signature with those parameters, although there is one)
System::Runtime::InteropServices::Marshal::Copy(result, 0, buff, 16);
And this one
buff = reinterpret_cast<unsigned char>(&result);
But the error is Expression must be a modifiable lvalue

According to this MSDN documentation I used this and it appears to work
pin_ptr<unsigned char>buff = &result[0];

Related

How to I declare "LPTSTR" for Raku NativeCall?

Raku/Perl6
Windows
I am trying to code a Raku Native call to a C functions that uses a "LPTSTR". How do I declare that? Something like constant DWORD := int32; but for LPTSTR?
If it helps, I found this description: "LPTSTR is a [long] pointer to a (non-const) TCHAR string" and "LPTSTR: null-terminated string of TCHAR (Long Pointer)"
"LPTSTR" comes from "LPWSTR lpBuffer,"
LP = (long) pointer, TSTR = either a wide string if UNICODE is defined, or an 8-bit string if not. So it's either a wchar_t * or unsigned char *. Determining which of these is in effect for the library you're using is probably quite difficult from Raku-space.

How can I transfer data from unsigned char * to char * safely?

I am willing to transfer data from unsigned char hash[512 + 1] to char res[512 + 1] safely.
My C hashing library MHASH returns a result so it can be printed as listed below.
for (int i = 0; i < size /*hash block size*/; i++)
printf("%.2x", hash[i]); // which is unsigned char - it prints normal hash characters in range [a-z,0-9]
printf("\n");
I am willing to do something like that (see below).
const char* res = (const char *)hash; // "hash" to "res"
printf("%s\n", res); // print "res" (which is const char*) - if i do this, unknown characters are printed
I know the difference between char and unsigned char, but I don't know how to transfer data. Any answer would be greatly appreciated, thanks in advance. But please do not recommend me C++ (STD) code, I am working on a project that is not STD-linked.
Given that the contents of the unsigned char array are printable characters, you can always safely convert it to char. Either a hardcopy with memcpy or a pointer reference as in the code you have already written.
I'm guessing that the actual problem here is that the unsigned char array contents are not actually printable characters, but integers in some format. You'll have to convert them from integer to ASCII letters. How to do this depends on the format of the data, which isn't clear in your question.
Assuming the following:
#define ARR_SIZE (512 + 1)
unsigned char hash[ARR_SIZE];
char res[ARR_SIZE];
/* filling up hash here. */
Just do:
#include <string.h>
...
memcpy(res, hash, ARR_SIZE);
Well, thank you guys for your answers, but unfortunately nothing worked yet. I am now sticking with the code below.
char res[(sizeof(hash) * 2) + 1] = { '\0' };
char * pPtr = res;
for (int i = 0; i < hashBlockSize; i++)
sprintf(pPtr + (i * 2), "%.2x", hash[i]);
return (const char *)pPtr;
Until there is any other much more performant way to get this done. It's right, my question is strongly related to MHASH Library.

Some info about CC_SHA256 objective-c

For a new project I need to hash a NSString with SHA256.
I have used the following code:
unsigned char hashedChars[32];
NSString *inputString;
inputString = [NSString stringWithFormat:#"hello"];
NSData * inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
CC_SHA256(inputData.bytes, inputData.length, hashedChars);
I found this piece of code on stackoverflow.
I do not really get all the things this code do here are some questions about the code:
1.The CC_SHA256 makes a hash but this hash will be stored in inputData again? What I mean can I do something like this:
NSString *string=CC_SHA256(..) //of course you can't put it directly in a NSString, but you get the point
2.In the end the hash has to be a hexadecimal string, but what is the type that CC_SHA256 outputs (UTF-8??)?
3.The first parameter of CC_SHA256 why do I have to put bytes at the end and is "inputData" enough?
4.What is the need of the length of the string (second parameter)?
5.And the last parameter does not make any sense to me, can somebody please explain and why the hashedChars has to be 32?
The argument list for CC_SHA256 is:
extern unsigned char *CC_SHA256(const void *data, CC_LONG len, unsigned char *md);
From the man page: https://developer.apple.com/library/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man3/CC_SHA256.3cc.html
Parameters explained:
*data is the input string, what you want to be hashed. It's a C string-type. A way to get this is to call 'inputData.bytes', with inputData a NSData object.
len is the length of the input string. As you'll realize if you'll start working with C strings, it's pretty normal for functions working with strings to ask for the length. That's because in C strings are just a sequence of bytes, and while text strings are generally terminated by a null byte, binary strings can have any length. It's also for safety ("buffer overflows").
*md is the output. Again, this is returned as a C string, of fixed length 32 bytes for SHA256 (that's why you don't see an outputLength parameter).
The output is "not relevant", but can be used to check if the function ran properly: if(CC_SHA256(...)) { all ok; }
The result string is stored into *md, and it's a binary C string, 32 bytes long. It's 32 bytes long because that's the length of SHA256 digests; for example, 16 bytes for MD5, 20 bytes for SHA1, etc. It's just how the algorithm works!
The output is just a binary string. If you want to make it into hex format you need to store it into a NSData object, and then get a hex representation of it:
NSData *resultData = [NSData dataWithBytes:hashedChars length:32];
To get the hex representation then look at this SO answer: https://stackoverflow.com/a/25378464/192024
If anyone trying to find a similar function for Android, the below snippet produces the same output as CC_SHA256
public static String calculateSH256(String secret){
final MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-256");
byte[] bytes = secret.getBytes("UTF-8");
digest.update(bytes, 0, bytes.length);
String sig = bytesToHex(digest.digest());
return sig;
}
catch (NoSuchAlgorithmException | UnsupportedEncodingException e){
throw new RuntimeException("Cannot calculate signature");
}
}
final protected static char[] hexArray = "0123456789abcdef".toCharArray();
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}

Using C style unsigned char array and bitwise operators in Swift

I'm working on changing some Objective-C Code over to Swift, and I cannot figure out for the life of me how to take care of unsigned char arrays and bitwise operations in this specific instance of code.
Specifically, I'm working on converting the following Objective-C code (which deals with CoreBluetooth) to Swift:
unsigned char advertisementBytes[21] = {0};
[self.proximityUUID getUUIDBytes:(unsigned char *)&advertisementBytes];
advertisementBytes[16] = (unsigned char)(self.major >> 8);
advertisementBytes[17] = (unsigned char)(self.major & 255);
I've tried the following in Swift:
var advertisementBytes: CMutablePointer<CUnsignedChar>
self.proximityUUID.getUUIDBytes(advertisementBytes)
advertisementBytes[16] = (CUnsignedChar)(self.major >> 8)
The problems I'm running into are that getUUIDBytes in Swift seems to only take a CMutablePointer<CUnsignedChar> object as an argument, rather than an array of CUnsignedChars, so I have no idea how to do the later bitwise operations on advertisementBytes, as it seems it would need to be an unsignedChar array to do so.
Additionally, CMutablePointer<CUnsignedChar[21]> throws an error saying that fixed length arrays are not supported in CMutablePointers in Swift.
Could anyone please advise on potential work-arounds or solutions? Many thanks.
Have a look at Interacting with C APIs
Mostly this
C Mutable Pointers
When a function is declared as taking a CMutablePointer
argument, it can accept any of the following:
nil, which is passed as a null pointer
A CMutablePointer value
An in-out expression whose operand is a stored lvalue of type Type,
which is passed as the address of the lvalue
An in-out Type[] value,
which is passed as a pointer to the start of the array, and
lifetime-extended for the duration of the call
If you have declared a
function like this one:
SWIFT
func takesAMutablePointer(x: CMutablePointer<Float>) { /*...*/ } You
can call it in any of the following ways:
SWIFT
var x: Float = 0.0
var p: CMutablePointer<Float> = nil
var a: Float[] = [1.0, 2.0, 3.0]
takesAMutablePointer(nil)
takesAMutablePointer(p)
takesAMutablePointer(&x)
takesAMutablePointer(&a)
So you code becomes
var advertisementBytes = CUnsignedChar[]()
self.proximityUUID.getUUIDBytes(&advertisementBytes)
advertisementBytes[16] = CUnsignedChar(self.major >> 8)

Copy two dimensional arrays using pointers

I want to copy two dimensional arrays and I made this function but it caused a compilation error
void Cpy_2d_arr(unsigned char *from,unsigned char *to)
{
unsigned char col,row;
for (row=0;row<4;row++)
{
for(col=0;col<4;col++)
{
(*(*(to+row)+col)) = (*(*(from+row)+col));
}
}
}
The two dimensional arrays are
unsigned char arr[4][4] = {'7','8','9','-','4','5','6','*','1','2','3','-','c','0','=','+'};
the target is an array inside a struct with the same size
the errors are :
1- Error 8 expected 'unsigned char ' but argument is of type 'unsigned char ()[4]
2- Error 11 subscripted value is neither array nor pointer
3- Error 11 invalid type argument of unary '*' (have 'int')
char arr[4][4] = {'7','8','9','-','4','5','6','*','1','2','3','-','c','0','=','+'};
is an array of pointers
void Cpy_2d_arr(unsigned char *from,unsigned char *to)
receives an single pointer( e.g. to an array of chars).
the types of your parameters are not compatible, change it to
void Cpy_2d_arr(unsigned char from[4][4],unsigned char to[4][4])
it should work just fine