Sending Hex and String to UDP - cocoa

I am trying to send commands to a server, through UDP. The server requires a few hex bytes at the beginning, though PHP this is easy
'\xFF\xFFcmd command variable'
Then I fwrite() that without a problem.
Now I am building a client in Cocoa and I cannot get the server to understand me at all, the data is sent, but I think it is incorrect or corrupt. I am trying to do it with CocoaAsyncSocket..
NSString *msg = [NSString stringWithFormat:#"%c%ccmd command variable",0xFF,0xFF];[socket connectToHost:#"85.25.248.160" onPort:28960 error:nil];
unsigned char lendata = [msg length];
NSMutableData *senddata = [NSMutableData dataWithBytes: &lendata length:sizeof(lendata)] ;
[senddata appendData:[msg dataUsingEncoding:NSUTF8StringEncoding]];
[socket sendData:senddata withTimeout:-1 tag:0];
NSLog of msg is 'ˇˇcmd command variable' but nothing occurs on the server, which I don't have access to, to listen for a malformed packet.
My guess is that by putting the 0xFF into the string, it is no longer the same, and is sent wrongly..

Solved problem. The NSString was messing with the \xff.
char *bytes = "\xff\xffcmd command variable";
NSData* data = [[NSData alloc] initWithBytes:bytes length:strlen(bytes)];
[socket sendData:data withTimeout:-1 tag:0];
To get variable as an NSString or something else..
char *bytes = "\xff\xff";
NSString *commands = [[NSString alloc] initWithFormat:#"command %#", variable];
NSMutableData *data = [[NSMutableData alloc] initWithBytes:bytes length:strlen(bytes)];
[data appendData:[commands dataUsingEncoding:NSUTF8StringEncoding]];
[socket sendData:data withTimeout:-1 tag:0];

Related

finding word after the match using NSString

I have varius log files to read. Each logs contain a report of a devices (printers).
What I can find is always the word 'firmware:' followed by the firmware revision like:
PTRE firmware: XER8673B2
The log does not seem to be very ordered, whereby the position of this text is not always on the same point or on the same line, but is always in the "PTRE firmawre: XXXXXXX" format.
How can I find XER8673B2 ? Any help is appreciated.
SOLVED (thanks to #roman-sausarnes), this is the code:
NSString *stringToSearch = [[NSString alloc] initWithContentsOfFile:#"path/to/log" encoding:NSUTF8StringEncoding error:nil];
NSString *preMatchString = #"PTRE firmware: ";
NSString *terminatingCharacter = #" ";
NSString *result = [[NSString alloc] init];
NSScanner *scanner = [NSScanner scannerWithString:stringToSearch];
[scanner scanUpToString:preMatchString intoString:NULL];
[scanner scanString:preMatchString intoString:NULL];
[scanner scanUpToString:terminatingCharacter intoString:&result];
NSLog(#"It's : %#", result);
The output is
It's : XER8673B2
Look at NSScanner. The code would look something like this:
NSString *stringToSearch = theStringThatYouWantToSearch;
NSString *preMatchString = #"firmware: ";
NSString *terminatingCharacter = " ";
NSString *result = [[NSString alloc] init];
NSScanner *scanner = [NSScanner scannerWithString:stringToSearch];
[scanner scanUpToString:preMatchString intoString:NULL];
[scanner scanString:preMatchString intoString:NULL];
[scanner scanUpToString:terminatingCharacter intoString:&result];
At the end, result should be the string that came after "firmware: " but before the next trailing space (" ").

Implementing a file format to be used with Encryption - Cocoa

I need to implement salts in my encryption, but to do so, I need to store it in a file format that I need to create so I can later retrieve it to decrypt. I'm a noob when it comes to encryption. The specifications of the file format should be as so:
Ciphertext: length of ciphertext ;
Salt: length of salt ;
Then the ciphertext and salt written out. This is where xcode really confuses me, as in creating a new file, etc.
How can I do this? And then retrieve the salt for decryption?
Thank you, your help is greatly appreciated.
You might consider using NSMutableDictionary and NSKeyedUnarchiver like this:
// Example ciphertext and salt
NSString *ciphertext = #"the ciphertext";
NSString *salt = #"the salt";
// File destination
NSString *path = #"/Users/Anne/Desktop/Archive.dat";
// Create dictionary with ciphertext and salt
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:ciphertext forKey:#"ciphertext"];
[dictionary setObject:salt forKey:#"salt"];
// Archive dictionary and write to file
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dictionary];
[data writeToFile:path options:NSDataWritingAtomic error:nil];
// Read file and unarchive
NSMutableDictionary *theDictionary = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
// Get ciphertext and salt
NSString *theCiphertext = [theDictionary objectForKey:#"ciphertext"];
NSString *theSalt = [theDictionary objectForKey:#"salt"];
// Show Result
NSLog(#"Extracted ciphertext: %#",theCiphertext);
NSLog(#"Extracted salt: %#",theSalt);
Output:
Extracted ciphertext: the ciphertext
Extracted salt: the salt
EDIT
Response to comment: Both NSData and NSString feature length.
Quick example:
NSString *theString = #"Example String";
NSData *theData = [theString dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger stringLength = [theString length];
NSUInteger dataLength = [theData length];
NSLog(#"String length: %ld",stringLength);
NSLog(#"Data length: %ld",dataLength);
Output:
String length: 14
Data length: 14

Cocoa AES Encryption NSData and Bytearrays

I'm using the following code to encrypt files in cocoa:
- (NSData *)AES256EncryptWithKey:(NSString *)key
{
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
bzero( keyPtr, sizeof( keyPtr ) ); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof( keyPtr ) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt( kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted );
if( cryptStatus == kCCSuccess )
{
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free( buffer ); //free the buffer
return nil;
}
And wrote this for the connection to the file:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"foo" ofType:#"rtf"];
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSString *key = [withFileKey stringValue];
NSString *newStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSString *encrypted = [newStr AES256EncryptWithKey:key];
NSLog(#"File encryption:%#", encrypted);
[filePathName setStringValue:filePath];
if (!data) {
NSLog(#"Unable to read file");
}
Basically what I did was first of all get the filepath of the file the user wants. Then convert the data in the file to a string. Then encrypt that string with the AES256EncryptWithKey: method. However, when I decrypt a plain text file for example, it returns a bunch of garbage like fonts and all that stuff, then the few lines I wrote. Something like this:
\ansicpg1252\cocoartf1138\cocoasubrtf100
{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 Menlo-Bold;}
{\colortbl;\red255\green255\blue255;}
\margl1440\margr1440\vieww10800\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
\f0\fs24 \cf0 Hello my name is bobby bob\
\
\pard\tx560\pardeftab560\pardirnatural
\f1\b\fs22 \cf0 \CocoaLigature0 YAY!\
and I am awesome!!}
Shouldn't I be taking the data and then encrypting that (conversion to bytes), then convert the encrypted data and convert it to a string to display? I tried something like that but it didn't work. :(
Something like:
NSData *encryptedData = [data AES256EncryptWithKey:yourkey];
And then:
NSString *convertData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
?
Your help is greatly appreciated. Thanks!
Your code appears hard-coded to load foo.rtf. This looks like an RTF file. Where is the "plain text file" you're talking about?
EDIT We had a lot of discussion on this, so I wrote up a blog post about how to correctly use CCCrypt().

Trying to get bytes and append using NSMutableData for a video through Asset Library gives memory full error

I’m trying to upload a video of size 100MB through Asset Library. But when i try to use -(NSUInteger)getBytes:(uint8_t *)buffer fromOffset:(long long)offset length:(NSUInteger)length error:(NSError **)error of ALAssetRepresentation I get memory full error. I also need to put the data in buffer to NSData. How can i achieve that?
I tried this way:
Byte *buffer = (Byte*)malloc(asset.defaultRepresentation.size);
NSUInteger k = [asset.defaultRepresentation getBytes:buffer fromOffset: 0.0
length:asset.defaultRepresentation.size error:nil];
NSData *adata = NSData *adata = [NSData dataWithBytesNoCopy:buffer
length:j freeWhenDone:YES];
It really works!
As #runeb said the answer is not working properly with large files. You should do something like that:
int bufferSize = 2048;
int offset = 0;
NSString* name=nil;
while(offset<asset.size){
Byte *buffer = (Byte*)malloc(bufferSize);
NSUInteger buffered = [asset getBytes:buffer fromOffset:offset length:bufferSize error:nil];
NSData *data;
data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:NO];
if(!name){
//Creates the file and gives it a unique name
name = [FileUtils saveVideoFromAsset:data];
}
else{
//Append data to the file created...
[FileUtils appendData:data toFile:name];
}
offset+=buffered;
free(buffer);
}
In order to append data to a file you can use that:
NSFileHandle *myHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
[myHandle seekToEndOfFile];
[myHandle writeData:videoData];
I hope that helps!
ust add #autoreleasepool block, so that any autorleased objects should be cleaned up. it looks like that ARC has something changed after iOS7
#autoreleasepool {
NSUInteger readStatus = [rep getBytes:buffer fromOffset:_startFromByte length:chunkSize error:NULL];
}

calling a C function using cocoa

I have a C function with the following method signature.
NSString* md5( NSString *str )
How do I call this function, pass in a string, and save the returned string?
I tried the following, but it did not work:
NSString *temp= [[NSString alloc]initWithString:md5(password)];
thanks for your help
You're making it too hard. The stuff in []'s is effectively smalltalk. What you want is to just call the function in C:
NSString * temp = md5(password);
What is password? Is password a common "char *" pointer? Is the md5 signature you put correct?
If that's the case, you could:
NSString *temp = [[NSString alloc] initWithCString:password encoding:NSASCIIStringEncoding];
If your md5 signature is: char *md5(char *password), and you have you password stored in a NSString, you could:
NSString password = #"mypass";
char buff[128];
NSString *temp = [[NSString alloc] initWithString:password];
[temp getCString:buff maxLength:128 encoding:NSASCIIStringEncoding];
char *md5 = md5(buff);
// then you could do whatever you want with md5 var

Resources