Xcode scanf char count - xcode

I found out in Xcode command line tool you can enter int into the code yourself with scanf.
When I tried this for a NSString, it didn't worked, and I found out scanf returns an integer, so my question is, what do you use to enter a NSString and save it into a variable, like:
int number;
scanf("%i", &number);
EDIT:
Now I found a code, but it only shows the first char:
char naamchar[40];
int nChars = scanf("%39s", naamchar);
NSString * naam = [[NSString alloc] initWithBytes:naamchar
length:nChars
encoding:NSUTF8StringEncoding];
naam is only 1 char :(
EDIT SOLUTION:
char naamchar[40];
scanf("%39s", naamchar);
NSString * naam = [NSString stringWithCString:naamchar encoding:NSUTF8StringEncoding];
...

man 3 scanf mentions:
These functions return the number of input items assigned.
nChars is set returning the number of items matched, in this case 1, not the number of characters in the string.
try replacing nChars with strlen(naamchar) i.e.
char naamchar[40];
int nChars = scanf("%39s", naamchar);
NSString * naam = [[NSString alloc] initWithBytes:naamchar
length:strlen(naamchar)
encoding:NSUTF8StringEncoding];
be sure to check for nChars == 0, which would indicate that there was no input to scan.

Related

AES Encryption is not working (Xcode)

I'm trying to encrypt string in Xcode to PHP with AES128 method by using following code:
Xcode
- (NSData*)AES256EncryptWithKey:(NSString*)key {
char keyPtr[kCCKeySizeAES256];
[key cStringUsingEncoding:NSASCIIStringEncoding];
NSString *iv = #"fdsfds85435nfdfs";
char ivPtr[kCCKeySizeAES128];
[iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSASCIIStringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, NULL,
keyPtr, kCCKeySizeAES256,
ivPtr,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess)
{
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer); //free the buffer;
return nil;
}
But when I run above coding, following result is not what I expect to be:
NSString *key = #"89432hjfsd891787";
NSData *plaintext = [[#"aaa0000000000000" dataUsingEncoding:NSASCIIStringEncoding] AES256EncryptWithKey: key];
NSString *mystring = [[NSString alloc] initWithData:plaintext encoding:NSASCIIStringEncoding];
NSLog(#"mystring %#", mystring);
OUTPUT is
uçó)â½S/èRÅ
What I want it something like that.
m9FNGM9IiwibWFjIjoiNmJkYzNmZTA5
Note: due to a coding error the keyPtr is not set to the key value, it becomes the value of the uninitialized memory.
You get "uçó)â½S/èRÅ" because you try to create a string from the data and there are a couple reasons this will not work.
Many data bytes do not map to printable ASCII characters or to any unicode character.
A data byte can be 0 (1 in 256 bytes on average will be 0x00) and that is a terminator for a "C" string so the string will be short.
There are two general conventions for encoding data into a string representation:
Hex-ascii where each data byte is encoded into two characters 0-9a-f.
Base64 where each 3 data data bytes are encoded into 4 ASCII characters.
You are probably looking for Base64 encoding:
NSString *mystring = [plaintext base64EncodedStringWithOptions:0];
Other errors in the code:
[key cStringUsingEncoding:NSASCIIStringEncoding]; The string may not be ASCII, better to use NSUTF8StringEncoding. Note that the output is not captured.
The keyPtr is never set to the key value, see above.
The key size id specified as 256-bits (32-bytes) but the key is 16 characters, use a key size that matched the key.
char ivPtr[kCCKeySizeAES128], an iv size is the block size not the key size: kCCBlockSizeAES128.
Looks like you want a Base64 encoded string.
NSString *mystring = [plaintext base64EncodedStringWithOptions:0];

Convert 16 (0xEFF) to NSString

Hey I have stuck on how to convert my int value to NSString and get correct value
I have unsigned int
unsigned int r = 0xEFF;
and I like to have NSString like #"EFF", not #"3839"
You can use the same format strings as printf:
NSString* newString = [NSString stringWithFormat:#"%x", r];

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().

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

Best way to escape characters like newline and double-quote in NSString

Say I have an NSString (or NSMutableString) containing:
I said "Hello, world!".
He said "My name's not World."
What's the best way to turn that into:
I said \"Hello, world!\".\nHe said \"My name\'s not World.\"
Do I have to manually use -replaceOccurrencesOfString:withString: over and over to escape characters, or is there an easier way? These strings may contain characters from other alphabets/languages.
How is this done in other languages with other string classes?
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding
I don't think there is any built-in method to "escape" a particular set of characters.
If the characters you wish to escape is well-defined, I'd probably stick with the simple solution you proposed, replacing the instances of the characters crudely.
Be warned that if your source string already has escaped characters in it, then you'll probably want to avoid "double-escaping" them. One way of achieving this would be to go through and "unescape" any escaped character strings in the string before then escaping them all again.
If you need to support a variable set of escaped characters, take a look at the NSScanner methods "scanUpToCharactersFromSet:intoString:" and "scanCharactersFromSet:intoString:". You could use these methods on NSScanner to cruise through a string, copying the parts from the "scanUpTo" section into a mutable string unchanged, and copying the parts from a particular character set only after escaping them.
This will escape double quotes in NSString:
NSString *escaped = [originalString stringByReplacingOccurrencesOfString:#"\"" withString:#"\\\""];
So you need to be careful and also escape the escape character...
I think in cases like these, it's useful to operate on a character at a time, either in UniChars or UTF8 bytes. If you're using UTF-8, then vis(3) will do most of the work for you (see below). Can I ask why you want to escape a single-quote within a double-quoted string? How are you planning to handle multi-byte characters? In the example below, I'm using UTF-8, encoding 8-bit characters using C-Style octal escapes. This can also be undone by unvis(3).
#import <Foundation/Foundation.h>
#import <vis.h>
#interface NSString (Escaping)
- (NSString *)stringByEscapingMetacharacters;
#end
#implementation NSString (Escaping)
- (NSString *)stringByEscapingMetacharacters
{
const char *UTF8Input = [self UTF8String];
char *UTF8Output = [[NSMutableData dataWithLength:strlen(UTF8Input) * 4 + 1 /* Worst case */] mutableBytes];
char ch, *och = UTF8Output;
while ((ch = *UTF8Input++))
if (ch == '\'' || ch == '\'' || ch == '\\' || ch == '"')
{
*och++ = '\\';
*och++ = ch;
}
else if (isascii(ch))
och = vis(och, ch, VIS_NL | VIS_TAB | VIS_CSTYLE, *UTF8Input);
else
och+= sprintf(och, "\\%03hho", ch);
return [NSString stringWithUTF8String:UTF8Output];
}
#end
int
main(int argc, const char *argv[])
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSLog(#"%#", [#"I said \"Hello, world!\".\nHe said \"My name's not World.\"" stringByEscapingMetacharacters]);
[pool drain];
return 0;
}
This is a snippet I have used in the past that works quite well:
- (NSString *)escapeString:(NSString *)aString
{
NSMutableString *returnString = [[NSMutableString alloc] init];
for(int i = 0; i < [aString length]; i++) {
unichar c = [aString characterAtIndex:i];
// if char needs to be escaped
if((('\\' == c) || ('\'' == c)) || ('"' == c)) {
[returnString appendFormat:#"\\%c", c];
} else {
[returnString appendFormat:#"%c", c];
}
}
return [returnString autorelease];
}
Do this:
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unencodedString,
NULL,
(CFStringRef)#"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8 );
Reference: http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/
You might even want to look into using a regex library (there are a lot of options available, RegexKit is a popular choice). It shouldn't be too hard to find a pre-written regex to escape strings that handles special cases like existing escaped characters.

Resources