patternMinor
Rot47 an NSString Category
Viewed 0 times
nsstringcategoryrot47
Problem
As a Java native, I am always a little worried when doing Objective-C because of memory leaks and pointers flying at my head...
All comments are welcome on the
GitHub
All comments are welcome on the
Category below. The Category functions are correct.GitHub
#import "NSString+r47.h"
@implementation NSString (r47)
-(NSString *) r47String
{
const char *_string = [self cStringUsingEncoding:NSASCIIStringEncoding];
int stringLength = [self length];
char newString[stringLength+1];
int x;
for( x=0; x<stringLength; x++ )
{
unsigned int aCharacter = _string[x];
if( 0x20 < aCharacter && aCharacter < 0x7F ) // from ! to ~
newString[x] = (((aCharacter - 0x21) + 0x2F) % 0x5E) + 0x21;
else // Not an r47 character
newString[x] = aCharacter;
}
newString[x] = '\0';
NSString *rotString = [NSString stringWithCString:newString encoding:NSASCIIStringEncoding];
DLog(@"%@ = %@",self,rotString);
return rotString ;
}
@endSolution
The question title suggested that this would be a
This is Objective-C, not C or C++ or any other language where cryptic terseness is favored. We prefer verboseness. The category should be called
In Objective-C, we also prefer our opening braces go on the same line, not on their own line. For example:
Braces are technically optional, but you really shouldn't think of them as such. Apple even agrees and made them non-optional in swift. You've left them out of your
When we implement categories on Foundation classes, we should take care to ensure their portability. The method should be designed to work no matter what project we import this file into and no matter what the contents of the string.
The problem here is that your method doesn't do that. Your method works fine presuming a particular encoding, but for anything else it will produce incorrect results.
Rather than a
Now
Rot47 category on NSString, but it's not. It's an r47 category (which tells me nothing... what's "r47"?).This is Objective-C, not C or C++ or any other language where cryptic terseness is favored. We prefer verboseness. The category should be called
Rot47. This should be @implementation NSString (Rot47). The method should be called - (NSString *)rot47String;In Objective-C, we also prefer our opening braces go on the same line, not on their own line. For example:
for (;;) {Braces are technically optional, but you really shouldn't think of them as such. Apple even agrees and made them non-optional in swift. You've left them out of your
if/else blocks, which is a great way to leave your code open for future bugs.When we implement categories on Foundation classes, we should take care to ensure their portability. The method should be designed to work no matter what project we import this file into and no matter what the contents of the string.
The problem here is that your method doesn't do that. Your method works fine presuming a particular encoding, but for anything else it will produce incorrect results.
Rather than a
char array, we need a unichar array.NSUInteger length = [self length];
unichar letters[length + 1];
[self getCharacters:letters range:NSMakeRange(0,length)];Now
letters is an array of unichars for us to iterate over and transform correctly.Code Snippets
NSUInteger length = [self length];
unichar letters[length + 1];
[self getCharacters:letters range:NSMakeRange(0,length)];Context
StackExchange Code Review Q#20025, answer score: 5
Revisions (0)
No revisions yet.