iPhone – 敲定苹果模糊的“VerificationController.m”

我正在尝试实施Apple发布的新的VerificationController.m类,以修复应用内购买欺诈问题。

就像苹果公司发布的所有东西一样,这是一个更加模糊,不完整和糟糕的解释性文件,有很多空洞和未知,无法被所有人所了解/理解。

我试图实现,但在代码的结尾,我们看到这四个方法:

- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length { #warning Replace this method. return nil; } - (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length { #warning Replace this method. return nil; } #warning Implement this function. char* base64_encode(const void* buf, size_t size) { return NULL; } #warning Implement this function. void * base64_decode(const char* s, size_t * data_len) { return NULL; } 

你可以看到,苹果懒得在代码的末尾实现C函数。 由于我的C / C ++能力太差,我看到我需要在C / C ++中实现这两个函数,并且它们必须返回char和void(???)。 其他人已经发布了这样做的例程,但他们是在Objective-C或不返回字符和无效(??)。

注意:这是我有另一个问题:如果一个方法被苹果在这种forms使用,如何返回无效?

 uint8_t *purchase_info_bytes = base64_decode([purchase_info_string cStringUsingEncoding:NSASCIIStringEncoding], &purchase_info_length); 

不应该返回uint8_t?

注2:我有另一个问题是,苹果说base64_encode是必需的,但没有被用于他们提供的代码。 我认为他们正在抽坏的东西,或者我的C / C ++知识真的很臭。

所以,回到我的第一个问题。 有人可以发表/指出一个方法,可以做的工作,遵循声明的方法base64_encode和base64_decode的要求? 请不要发布不符合苹果公司的这些要求的objective-c方法。

谢谢。

这个解决scheme应该是非常简单的,其中包括填充缺失信息的所有方法。 在沙箱中testing和function。

 // single base64 character conversion static int POS(char c) { if (c>='A' && c<='Z') return c - 'A'; if (c>='a' && c<='z') return c - 'a' + 26; if (c>='0' && c<='9') return c - '0' + 52; if (c == '+') return 62; if (c == '/') return 63; if (c == '=') return -1; [NSException raise:@"invalid BASE64 encoding" format:@"Invalid BASE64 encoding"]; return 0; } - (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length { return [NSString stringWithUTF8String:base64_encode(input, (size_t)length)]; } - (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length { size_t retLen; uint8_t *retStr = base64_decode([input UTF8String], &retLen); if (length) *length = (NSInteger)retLen; NSString *st = [[[NSString alloc] initWithBytes:retStr length:retLen encoding:NSUTF8StringEncoding] autorelease]; free(retStr); // If base64_decode returns dynamically allocated memory return st; } char* base64_encode(const void* buf, size_t size) { static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; char* str = (char*) malloc((size+3)*4/3 + 1); char* p = str; unsigned char* q = (unsigned char*) buf; size_t i = 0; while(i < size) { int c = q[i++]; c *= 256; if (i < size) c += q[i]; i++; c *= 256; if (i < size) c += q[i]; i++; *p++ = base64[(c & 0x00fc0000) >> 18]; *p++ = base64[(c & 0x0003f000) >> 12]; if (i > size + 1) *p++ = '='; else *p++ = base64[(c & 0x00000fc0) >> 6]; if (i > size) *p++ = '='; else *p++ = base64[c & 0x0000003f]; } *p = 0; return str; } void* base64_decode(const char* s, size_t* data_len_ptr) { size_t len = strlen(s); if (len % 4) [NSException raise:@"Invalid input in base64_decode" format:@"%d is an invalid length for an input string for BASE64 decoding", len]; unsigned char* data = (unsigned char*) malloc(len/4*3); int n[4]; unsigned char* q = (unsigned char*) data; for(const char*p=s; *p; ) { n[0] = POS(*p++); n[1] = POS(*p++); n[2] = POS(*p++); n[3] = POS(*p++); if (n[0]==-1 || n[1]==-1) [NSException raise:@"Invalid input in base64_decode" format:@"Invalid BASE64 encoding"]; if (n[2]==-1 && n[3]!=-1) [NSException raise:@"Invalid input in base64_decode" format:@"Invalid BASE64 encoding"]; q[0] = (n[0] << 2) + (n[1] >> 4); if (n[2] != -1) q[1] = ((n[1] & 15) << 4) + (n[2] >> 2); if (n[3] != -1) q[2] = ((n[2] & 3) << 6) + n[3]; q += 3; } // make sure that data_len_ptr is not null if (!data_len_ptr) [NSException raise:@"Invalid input in base64_decode" format:@"Invalid destination for output string length"]; *data_len_ptr = q-data - (n[2]==-1) - (n[3]==-1); return data; } 

这里是NSStringNSString的基本64位编码函数:

 +(NSString *) encodeString:(NSString *)inString { NSData *data = [inString dataUsingEncoding:NSUTF8StringEncoding]; //Point to start of the data and set buffer sizes int inLength = [data length]; int outLength = ((((inLength * 4)/3)/4)*4) + (((inLength * 4)/3)%4 ? 4 : 0); const char *inputBuffer = [data bytes]; char *outputBuffer = malloc(outLength); outputBuffer[outLength] = 0; //64 digit code static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //start the count int cycle = 0; int inpos = 0; int outpos = 0; char temp; outputBuffer[outLength-1] = '='; outputBuffer[outLength-2] = '='; while (inpos < inLength){ switch (cycle) { case 0: outputBuffer[outpos++] = Encode[(inputBuffer[inpos]&0xFC)>>2]; cycle = 1; break; case 1: temp = (inputBuffer[inpos++]&0x03)<<4; outputBuffer[outpos] = Encode[temp]; cycle = 2; break; case 2: outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xF0)>> 4]; temp = (inputBuffer[inpos++]&0x0F)<<2; outputBuffer[outpos] = Encode[temp]; cycle = 3; break; case 3: outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xC0)>>6]; cycle = 4; break; case 4: outputBuffer[outpos++] = Encode[inputBuffer[inpos++]&0x3f]; cycle = 0; break; default: cycle = 0; break; } } NSString *pictemp = [NSString stringWithUTF8String:outputBuffer]; free(outputBuffer); return pictemp; } 

这是NSStringNSString的base 64解码函数:

 +(NSString *) decodeString:(NSString *)inString { const char* string = [inString cStringUsingEncoding:NSASCIIStringEncoding]; NSInteger inputLength = inString.length; static char decodingTable[128]; static char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; for (NSInteger i = 0; i < 128; i++) { decodingTable[encodingTable[i]] = i; } if ((string == NULL) || (inputLength % 4 != 0)) { return nil; } while (inputLength > 0 && string[inputLength - 1] == '=') { inputLength--; } NSInteger outputLength = inputLength * 3 / 4; NSMutableData* data = [NSMutableData dataWithLength:outputLength]; uint8_t* output = data.mutableBytes; NSInteger inputPoint = 0; NSInteger outputPoint = 0; while (inputPoint < inputLength) { char i0 = string[inputPoint++]; char i1 = string[inputPoint++]; char i2 = inputPoint < inputLength ? string[inputPoint++] : 'A'; /* 'A' will decode to \0 */ char i3 = inputPoint < inputLength ? string[inputPoint++] : 'A'; output[outputPoint++] = (decodingTable[i0] << 2) | (decodingTable[i1] >> 4); if (outputPoint < outputLength) { output[outputPoint++] = ((decodingTable[i1] & 0xf) << 4) | (decodingTable[i2] >> 2); } if (outputPoint < outputLength) { output[outputPoint++] = ((decodingTable[i2] & 0x3) << 6) | decodingTable[i3]; } } NSLog(@"%@",data); NSString *finalString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; return finalString; } 

这些都是从我在互联网上不同地方find的例子中拼凑出来的,当时我正在search它们。 他们,可能会更容易执行。 我刚刚创build了一个Base64类,并在其中放置了这些方法。

下面是Justin答案的C包装:

 char* base64_encode(const void* buf, size_t size) { NSData* data = [NSData dataWithBytesNoCopy:(void*)buf length:size]; NSString* string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; return [[_Class_ encode:string] UTF8String]; } void* base64_Decode (const char* s, size_t* data_len) { NSString* result = [_Class_ decode:[NSString stringWithCString:s encoding:NSASCIIStringEncoding]]; *data_len = result.length; return [result UTF8String]; } 

其中Class是包含Justinfunction的类。