Swift String decoding, how to decode 8859 ( latin 1 ) string? - swift

Here is the data source, encoded by ISO-8859-1:
"x%DAe%91%C1%92%9B0%0C%86%9F%A5%3A%B3%C1%84%98%89%B9%F4%D0%F3%3EA%E9xd%5B%807%06S%23%B2%DD%EE%EC%BB%D7%24%E9%B4%9D%1E%3CcI%BF%A5O%BF%DF%21D%7B%D1%AF%23%21C%0BP%00%C7e%D5%26Et%16W%A6%04%ED%D7w%D8%BC%CB%D5s%D3%08%21T%16%AD6%26%82V%3Cn%BA%8Fi%DA%1B%EC%09%E2%DB%2B%A5%0A%C0e%E9%D1f%21%8C%CCK%DB%95%5D9%FA%80O%D5%E15%A2wq%1E%F6s%B0sW6%95%11%A7%DE%08el%D5%98S%D3H%A4%B3%B4u%AD%B0%E9%E5%09%0F%2F%CB%F0%D9O8%D0s%1C%D2%B1%2B%BFo%18%3C%BFue%25%C4%A7%AE%5C%FDOz%0A%7E%F2%DC%95gq%C9%99%1D%93%7E%40%5B%15%FB%8E%C8%3E%CE%19%E4%CB%E8g%CC%A5%D9%DB%CB%8C%D3%CE%26%A5%CC%89%40W%0A%D0%1E%B3%BC%0F8%40%3Bo%21%14%90b+%CDo%0B%DD%1A%E1%E6%7C%7C%DE%98%DC-%BCzG%BF%C3%BCz%22%0C%EC%27%FA%23%C0%8D%C7%982%E6%A3E%16e%A7%9D%1E%E3%1C%93%DEM%CD%F4b%9F%19%FC%95VF%BE%8B%B6%95%92%FE%D7Z%10%19r%B9%E8%87%F5w%BA5%26%BE3%27%1BW%D6%8F%25%B2%F5%7F%87%C7%EA%E3%5B%01%93%93%FA%FF%CF%05%7B%A6Z%2A%EC%8DR%27ekS%F7R%D6X%2BS%29stX%C1%C7%2F%7B%CD%B12"
I guess in swift, ISO-8859-1 is String.Encoding.isoLatin1
The content contained is
{"lock_wheat":"","topsSth":[{"uid":"8660009","score":0,"score_format":0,"setter":99,"appface":"http:hahaha","sex":1,"location":"China","nickname":"555","level":21,"flag":null,"role_type":1,"audioMuted":1,"videoMuted":0,"realtimeMuted":1,"authority_type":0,"head_honor_id":100021,"livestate":0,"user_score_format":"0","pk_score":null,"sort":21,"rcost_level":9,"cost_level":21}],"md5_tops_broadcaster":"666"}
PS: I edited some words above
I need to convert to the following Java code to Swift
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.Inflater;
public class HelloWorld {
public static String decompress(String data, String charset) throws UnsupportedEncodingException {
byte[] bytes = data.getBytes(charset);
byte[] output = new byte[0];
Inflater decompresser = new Inflater();
decompresser.reset();
decompresser.setInput(bytes);
ByteArrayOutputStream o = new ByteArrayOutputStream(bytes.length);
try {
byte[] buf = new byte[1024];
while (!decompresser.finished()) {
int i = decompresser.inflate(buf);
o.write(buf, 0, i);
}
output = o.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
o.close();
} catch (IOException e) {
e.printStackTrace();
}
}
decompresser.end();
return new String(output);
}
public static String decompress(String data) throws UnsupportedEncodingException {
String decodeTmp = URLDecoder.decode(data, "ISO-8859-1");
System.out.println(decodeTmp);
return decompress(decodeTmp, "ISO-8859-1");
}
public static void main(String[] args) {
String data = "x%DAe%91%C1%92%9B0%0C%86%9F%A5%3A%B3%C1%84%98%89%B9%F4%D0%F3%3EA%E9xd%5B%807%06S%23%B2%DD%EE%EC%BB%D7%24%E9%B4%9D%1E%3CcI%BF%A5O%BF%DF%21D%7B%D1%AF%23%21C%0BP%00%C7e%D5%26Et%16W%A6%04%ED%D7w%D8%BC%CB%D5s%D3%08%21T%16%AD6%26%82V%3Cn%BA%8Fi%DA%1B%EC%09%E2%DB%2B%A5%0A%C0e%E9%D1f%21%8C%CCK%DB%95%5D9%FA%80O%D5%E15%A2wq%1E%F6s%B0sW6%95%11%A7%DE%08el%D5%98S%D3H%A4%B3%B4u%AD%B0%E9%E5%09%0F%2F%CB%F0%D9O8%D0s%1C%D2%B1%2B%BFo%18%3C%BFue%25%C4%A7%AE%5C%FDOz%0A%7E%F2%DC%95gq%C9%99%1D%93%7E%40%5B%15%FB%8E%C8%3E%CE%19%E4%CB%E8g%CC%A5%D9%DB%CB%8C%D3%CE%26%A5%CC%89%40W%0A%D0%1E%B3%BC%0F8%40%3Bo%21%14%90b+%CDo%0B%DD%1A%E1%E6%7C%7C%DE%98%DC-%BCzG%BF%C3%BCz%22%0C%EC%27%FA%23%C0%8D%C7%982%E6%A3E%16e%A7%9D%1E%E3%1C%93%DEM%CD%F4b%9F%19%FC%95VF%BE%8B%B6%95%92%FE%D7Z%10%19r%B9%E8%87%F5w%BA5%26%BE3%27%1BW%D6%8F%25%B2%F5%7F%87%C7%EA%E3%5B%01%93%93%FA%FF%CF%05%7B%A6Z%2A%EC%8DR%27ekS%F7R%D6X%2BS%29stX%C1%C7%2F%7B%CD%B12";
try {
String dateNew = decompress(data);
System.out.println(dateNew);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here is what I tried:
I am obstructed at this java line
String decodeTmp = URLDecoder.decode(data, "ISO-8859-1");
Here prints
xÚeÁ0
¥:³Á¹ôÐó>Aéxd[7S#²Ýîì»×$é´<cI¿¥O¿ß!D{ѯ#!C
PÇeÕ&EtW¦í×wؼËÕs!T­6&V<nºiÚì âÛ+¥
ÀeéÑf!ÌKÛ]9úOÕá5¢wqös°sW6§elÕSÓH¤³´u­°éå /ËðÙO8ÐsÒ±+¿o<¿ue%ħ®\ýOz
~òÜgqÉ~#[ûÈ>ÎäËègÌ¥ÙÛËÓÎ&¥Ì#W
г¼8#;o!b Ío
Ýáæ||ÞÜ-¼zG¿Ã¼z"
ì'ú#ÀÇ2æ£Ee§ãÞMÍôbüVF¾¶þ×Zr¹èõwº5&¾3'Ö%²õÇêã[úÿÏ{¦Z*ìR'ekS÷R
as for URLDecoder in Java, I don't know such thing in Swift.

Here is Objective - C solution:
as #Martin R said, zlib
as #Sulthan said, deprecated since iOS 9
#include <zlib.h>
#implementation NSData (Compression)
#pragma mark -
#pragma mark Zlib Compression routines
- (NSData *) zlibInflate
{
if ([self length] == 0) return self;
unsigned full_length = [self length];
unsigned half_length = [self length] / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
BOOL done = NO;
int status;
z_stream strm;
strm.next_in = (Bytef *)[self bytes];
strm.avail_in = [self length];
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit (&strm) != Z_OK) return nil;
while (!done)
{
// Make sure we have enough room and reset the lengths.
if (strm.total_out >= [decompressed length])
[decompressed increaseLengthBy: half_length];
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = [decompressed length] - strm.total_out;
// Inflate another chunk.
status = inflate (&strm, Z_SYNC_FLUSH);
if (status == Z_STREAM_END) done = YES;
else if (status != Z_OK) break;
}
if (inflateEnd (&strm) != Z_OK) return nil;
// Set real length.
if (done)
{
[decompressed setLength: strm.total_out];
return [NSData dataWithData: decompressed];
}
else return nil;
}
#end
#implementation NSString (ZlibData)
- (NSDictionary *)transformZLibData{
NSString *str = [self stringByReplacingOccurrencesOfString:#"+" withString:#"%20"];
NSString *latin1String = [str stringByReplacingPercentEscapesUsingEncoding:NSISOLatin1StringEncoding];
NSData *latin1Data = [latin1String dataUsingEncoding:NSISOLatin1StringEncoding];
NSData *inflateData = [latin1Data zlibInflate];
if (![inflateData isKindOfClass:[NSData class]] || inflateData.length < 1) {
return nil;
}
id jsonObj = [NSJSONSerialization JSONObjectWithData:inflateData options:NSJSONReadingAllowFragments error:nil];
NSLog(#"%#", jsonObj);
if (![jsonObj isKindOfClass:[NSDictionary class]]) {
return nil;
}
return [NSDictionary dictionaryWithDictionary:(NSDictionary *)jsonObj];
}
#end
call like this:
let data = "x%DAe%91%C1%92%9B0%0C%86%9F%A5%3A%B3%C1%84%98%89%B9%F4%D0%F3%3EA%E9xd%5B%807%06S%23%B2%DD%EE%EC%BB%D7%24%E9%B4%9D%1E%3CcI%BF%A5O%BF%DF%21D%7B%D1%AF%23%21C%0BP%00%C7e%D5%26Et%16W%A6%04%ED%D7w%D8%BC%CB%D5s%D3%08%21T%16%AD6%26%82V%3Cn%BA%8Fi%DA%1B%EC%09%E2%DB%2B%A5%0A%C0e%E9%D1f%21%8C%CCK%DB%95%5D9%FA%80O%D5%E15%A2wq%1E%F6s%B0sW6%95%11%A7%DE%08el%D5%98S%D3H%A4%B3%B4u%AD%B0%E9%E5%09%0F%2F%CB%F0%D9O8%D0s%1C%D2%B1%2B%BFo%18%3C%BFue%25%C4%A7%AE%5C%FDOz%0A%7E%F2%DC%95gq%C9%99%1D%93%7E%40%5B%15%FB%8E%C8%3E%CE%19%E4%CB%E8g%CC%A5%D9%DB%CB%8C%D3%CE%26%A5%CC%89%40W%0A%D0%1E%B3%BC%0F8%40%3Bo%21%14%90b+%CDo%0B%DD%1A%E1%E6%7C%7C%DE%98%DC-%BCzG%BF%C3%BCz%22%0C%EC%27%FA%23%C0%8D%C7%982%E6%A3E%16e%A7%9D%1E%E3%1C%93%DEM%CD%F4b%9F%19%FC%95VF%BE%8B%B6%95%92%FE%D7Z%10%19r%B9%E8%87%F5w%BA5%26%BE3%27%1BW%D6%8F%25%B2%F5%7F%87%C7%EA%E3%5B%01%93%93%FA%FF%CF%05%7B%A6Z%2A%EC%8DR%27ekS%F7R%D6X%2BS%29stX%C1%C7%2F%7B%CD%B12"
if let dict = data.transformZLibData() as? [String:Any] { }

Related

3des encryption kCCAlignmentError error

I am trying to encrypt an xml string.After the encryption is done then the decrypt the encrypted d I am getting the string as ALIGNMENT.
I dont understand what is the reason
(NSString*) doCipher:(NSString*)plainText:(CCOperation)encryptOrDecrypt {
const void *vplainText;
size_t plainTextBufferSize;
if (encryptOrDecrypt == kCCDecrypt)
{
NSData *EncryptData = [NSData dataFromBase64String:plainText];
plainTextBufferSize = [EncryptData length];
vplainText = [EncryptData bytes];
}
else
{
plainTextBufferSize = [plainText length];
vplainText = (const void *) [plainText UTF8String];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
// uint8_t iv[kCCBlockSize3DES];
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
// memset((void *) iv, 0x0, (size_t) sizeof(iv));
NSString *key = #"123456789012345678901234";
NSString *initVec = #"init Vec";
const void *vkey = (const void *) [key UTF8String];
const void *vinitVec = (const void *) [initVec UTF8String];
ccStatus = CCCrypt(encryptOrDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
vkey, //"123456789012345678901234", //key
kCCKeySize3DES,
vinitVec, //"init Vec", //iv,
vplainText, //"Your Name", //plainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
//if (ccStatus == kCCSuccess) NSLog(#"SUCCESS");
//else/
if (ccStatus == kCCParamError) return #"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return #"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return #"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return #"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return #"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return #"UNIMPLEMENTED";
NSString *result;
if (encryptOrDecrypt == kCCDecrypt)
{
result = [ [NSString alloc] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIStringEncoding];
}
else
{
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [myData base64EncodedString];
}
return result;
}
kCCAlignmentError means that the data you are passing is not correctly padded (specifically that the entire data length including padding is not a multiple of the block size). The most likely cause is that you are truncating your encrypted data somewhere, possibly outside of this routine.
You should check your encrypted data at each step and make sure that it is always a multiple of the block size (8 bytes). You'll need to base64-decode before checking the length.

ZLib in iPhone unable to decompress data

I am trying to decompress data using the ZLib in iPhone, but it always through error of "Invalid header Check".
To compress the data I am using the following in Java
Implementation: Standard Java implementation for Zlib
Deflator : java.util.zip.Deflater
version 1.45, 04/07/06
Compression level: BEST_COMPRESSION
In iPhone the following is the code for decompressing:
- (NSData *)zlibInflate
{
if ([self length] == 0) return self;
unsigned full_length = [self length];
unsigned half_length = [self length] / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
BOOL done = NO;
int status;
z_stream strm;
strm.next_in = (Bytef *)[self bytes];
strm.avail_in = [self length];
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit (&strm) != Z_OK) return nil;
while (!done)
{
// Make sure we have enough room and reset the lengths.
if (strm.total_out >= [decompressed length])
[decompressed increaseLengthBy: half_length];
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = [decompressed length] - strm.total_out;
// Inflate another chunk.
status = inflate (&strm, Z_SYNC_FLUSH);
if (status == Z_STREAM_END) done = YES;
else if (status != Z_OK) {
NSLog(#"%s", strm.msg);
break;
}
}
if (inflateEnd (&strm) != Z_OK) return nil;
// Set real length.
if (done)
{
[decompressed setLength: strm.total_out];
return [NSData dataWithData: decompressed];
}
else return nil;
}
Following is a sample compressed string:
xÚÝUko²Jþ~?­ó?¥¾?¤?©?´ÚjCMX,Òµ?ª?µßVX¹È­?¿.øë_?¯¶ZÏ%íùxHH&Ã<ÏÌ3ÌÎ
#2.ðE?ºqþpéEzÏ09IoÒ?ª? ?®?£àÌönì$brÛ#fl95?¿»a//Tçáò?¢?¿½
µ©ÊÃÉPÔ¼:8y¦ý.äÎ?µ?¥?¼y?©ã¯9ö?¥½?¢±ÝûwÛ?§ãga?©á8?¨?­m\Õ?»6,'Îe?¬}(L}7ÆÅ6#gJ(¥7´s?¬d.ó,Ë°¦prßýÕÖ? 
Below is the function for compresser:
public static byte[] compress(String s) {
Deflater comp = new Deflater();
//comp.setLevel(Deflater.BEST_COMPRESSION);
comp.setInput(s.getBytes());
comp.finish();
ByteArrayOutputStream bos = new ByteArrayOutputStream(s.length());
// Compress the data
byte[] buf = new byte[1024];
try {
while (!comp.finished()) {
int count = comp.deflate(buf);
bos.write(buf, 0, count);
}
bos.close();
} catch (Exception e) {
//Log.d(TAG, e.getMessage());
e.printStackTrace();
}
// Get the compressed data
byte[] compressedData = bos.toByteArray();
// put in this fix for Symbol scanners
byte[] compressedDataForSymbol = mungeForSymbol(compressedData);
/*
* byte[] decompressedDataForSymbol =
* decompressedDataAfterSymbol(compressedDataForSymbol); // check they
* are the same for(int i=0;i<compressedData.length;i++) { if
* (compressedData[i] != decompressedDataForSymbol[i]) {
* //System.out.println("Error at " + i); } }
*/
return compressedDataForSymbol;
// return s.getBytes();
}
Using Java Deflater with default compression level creates output encoded data with header with first two bytes 0x78 0x9c. These are not used in IOS. Just remove the first two bytes and try the Inflate ie decompression in IOS. It should work.
I had faced the same issue, But i wanted data from IOS(compressed) to android(decompressed).

What is best available data encryption algorithm in IOS

i am trying to encrypt my data using before sending it to server, is there any highly secure two way encryption algorithm ? which one is best for this purpose.
Check ths once
Here, key is string variable, declare as a global variable.
add sequrity framework for your code and import
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
- (void)viewDidLoad
{
[super viewDidLoad];
key=#"Your own key";
// encoding
NSString *encodingString=[[self encrypt:[#"Your String"
dataUsingEncoding:NSUTF8StringEncoding]
base64EncodedString];;
//decoding
NSData *data=[self decrypt:[NSData dataFromBase64String:encryptString]];
NSString *decodingString = [[NSString alloc] initWithBytes:[data bytes] length:
[data length] encoding: NSASCIIStringEncoding];
}
- (NSData *) encrypt:(NSData *) plainText {
return [self transform:kCCEncrypt data:plainText];
}
- (NSData *) decrypt:(NSData *) cipherText {
return [self transform:kCCDecrypt data:cipherText];
}
- (NSData *) transform:(CCOperation) encryptOrDecrypt data:(NSData *) inputData {
// kCCKeySizeAES128 = 16 bytes
// CC_MD5_DIGEST_LENGTH = 16 bytes
NSData* secretKey = [ChipperObject md5:Key];
CCCryptorRef cryptor = NULL;
CCCryptorStatus status = kCCSuccess;
uint8_t iv[kCCBlockSizeAES128];
memset((void *) iv, 0x0, (size_t) sizeof(iv));
status = CCCryptorCreate(encryptOrDecrypt,
kCCAlgorithmAES128,kCCOptionPKCS7Padding,
[secretKey bytes], kCCKeySizeAES128, iv, &cryptor);
if (status != kCCSuccess) {
return nil;
}
size_t bufsize = CCCryptorGetOutputLength(cryptor, (size_t)[inputData length],
true);
void * buf = malloc(bufsize * sizeof(uint8_t));
memset(buf, 0x0, bufsize);
size_t bufused = 0;
size_t bytesTotal = 0;
status = CCCryptorUpdate(cryptor, [inputData bytes], (size_t)[inputData length],
buf, bufsize, &bufused);
if (status != kCCSuccess) {
free(buf);
CCCryptorRelease(cryptor);
return nil;
}
bytesTotal += bufused;
status = CCCryptorFinal(cryptor, buf + bufused, bufsize - bufused, &bufused);
if (status != kCCSuccess) {
free(buf);
CCCryptorRelease(cryptor);
return nil;
}
bytesTotal += bufused;
CCCryptorRelease(cryptor);
return [NSData dataWithBytesNoCopy:buf length:bytesTotal];
}
Here is my code using 3des CCCrypt Method,Find GTMBase64.h from googlecode, https://code.google.com/p/google-toolbox-for-mac/source/browse/trunk/Foundation/GTMBase64.h?r=87
#import <CommonCrypto/CommonCryptor.h>
#import "GTMBase64.h"
- (NSData*)TripleDES:(NSData*)plainData encryptOrDecrypt:(CCOperation)encryptOrDecrypt key:(NSString*)key {
const void *vplainText;
size_t plainTextBufferSize;
if (encryptOrDecrypt == kCCDecrypt)
{
NSData *EncryptData = [GTMBase64 decodeData:plainData];
plainTextBufferSize = [EncryptData length];
vplainText = [EncryptData bytes];
}
else
{
plainTextBufferSize = [plainData length];
vplainText = (const void *)[plainData bytes];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
// uint8_t ivkCCBlockSize3DES;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
// memset((void *) iv, 0x0, (size_t) sizeof(iv));
// NSString *key = #"123456789012345678901234";
NSString *initVec = #"init Vec";
const void *vkey = (const void *) [key UTF8String];
const void *vinitVec = (const void *) [initVec UTF8String];
ccStatus = CCCrypt(encryptOrDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
vkey, //"123456789012345678901234", //key
kCCKeySize3DES,
vinitVec, //"init Vec", //iv,
vplainText, //"Your Name", //plainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
//if (ccStatus == kCCSuccess) NSLog(#"SUCCESS");
/*else if (ccStatus == kCC ParamError) return #"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return #"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return #"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return #"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return #"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return #"UNIMPLEMENTED"; */
NSData *result;
if (encryptOrDecrypt == kCCDecrypt)
{
result = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
}
else
{
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [GTMBase64 encodeData:myData];
}
return result;
}
Usage
NSString *inputString = #"good";
//encode
NSData *inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
NSData *encriptdata = [self TripleDES:inputData encryptOrDecrypt:kCCEncrypt key:#"ff68f8e82961489a8b14b345"];
NSString *encodeString = [GTMBase64 stringByEncodingData:encriptdata];
NSLog(#"encodeString : %#" ,encodeString);
//decode
NSData *encodeData = [GTMBase64 decodeString:encodeString];
NSData *decodeData = [self TripleDES:encodeData encryptOrDecrypt:kCCDecrypt key:#"ff68f8e82961489a8b14b345"];
NSString *decodeString = [[NSString alloc] initWithBytes:[decodeData bytes] length:[decodeData length] encoding:NSUTF8StringEncoding];
NSLog(#"decodeString : %#" ,decodeString);
Public Key Infrastructure (PKI) offers you a trustworthy way to encrypt data between 2 machines. You can give it a try.
You can use HTTPS, or you can also use RC6 to encrypt your data.

Get Wifi Address Problem

I try to get ip address using asyncsocket framework. When do it via ethernet cable the following method works good.
But when try to get ip address using wifi access point it returns nil.
Here is a method:
- (NSData *)wifiAddress
{
// On iPhone, WiFi is always "en0"
NSData *result = nil;
struct ifaddrs *addrs;
const struct ifaddrs *cursor;
if ((getifaddrs(&addrs) == 0))
{
cursor = addrs;
while (cursor != NULL)
{
NSLog(#"cursor->ifa_name = %s", cursor->ifa_name);
if (strcmp(cursor->ifa_name, "en0") == 0)
{
if (cursor->ifa_addr->sa_family == AF_INET)
{
struct sockaddr_in *addr = (struct sockaddr_in *)cursor->ifa_addr;
NSLog(#"cursor->ifa_addr = %s", inet_ntoa(addr->sin_addr));
result = [NSData dataWithBytes:addr length:sizeof(struct sockaddr_in)];
cursor = NULL;
}
else
{
cursor = cursor->ifa_next;
}
}
else
{
cursor = cursor->ifa_next;
}
}
freeifaddrs(addrs);
}
return result;
}
The issue we had was that an exact match on en0 would not always return the wifi address. We have something similar to the following. Hope this helps.
NSString* wifiIp = [NetUtils getLocalAddress:#"en"];
+ (NSString *) getLocalAddress:(NSString*) interface
{
NSString *address = nil;
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
success = getifaddrs(&interfaces);
if (success == 0)
{
temp_addr = interfaces;
while(temp_addr != NULL)
{
if(temp_addr->ifa_addr->sa_family == AF_INET)
{
NSRange range = [[NSString stringWithUTF8String:temp_addr->ifa_name] rangeOfString : interface];
if(range.location != NSNotFound)
{
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
}
}
temp_addr = temp_addr->ifa_next;
}
}
freeifaddrs(interfaces);
return address;
}

How to convert an NSData to a zip file with objective-c [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How can I create a zip file by using Objective C?
I request a zip file from my server, using NSData to preserve the data.Then I want to save these data into a zip file, how can I do that with objective-c.
I use the following two methods.
Compress:
+(NSData*) compressData:(NSData*) uncompressedData {
if ([uncompressedData length] == 0) return uncompressedData;
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_out = 0;
strm.next_in=(Bytef *)[uncompressedData bytes];
strm.avail_in = (unsigned int)[uncompressedData length];
// Compresssion Levels:
// Z_NO_COMPRESSION
// Z_BEST_SPEED
// Z_BEST_COMPRESSION
// Z_DEFAULT_COMPRESSION
if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK) return nil;
NSMutableData *compressed = [NSMutableData dataWithLength:16384]; // 16K chunks for expansion
do {
if (strm.total_out >= [compressed length])
[compressed increaseLengthBy: 16384];
strm.next_out = [compressed mutableBytes] + strm.total_out;
strm.avail_out = (unsigned int)([compressed length] - strm.total_out);
deflate(&strm, Z_FINISH);
} while (strm.avail_out == 0);
deflateEnd(&strm);
[compressed setLength: strm.total_out];
return [NSData dataWithData:compressed];
}
Uncompress:
+(NSData*) uncompressGZip(NSData*) compressedData {
if ([compressedData length] == 0) return compressedData;
NSUInteger full_length = [compressedData length];
NSUInteger half_length = [compressedData length] / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
BOOL done = NO;
int status;
z_stream strm;
strm.next_in = (Bytef *)[compressedData bytes];
strm.avail_in = (unsigned int)[compressedData length];
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit2(&strm, (15+32)) != Z_OK) return nil;
while (!done) {
// Make sure we have enough room and reset the lengths.
if (strm.total_out >= [decompressed length]) {
[decompressed increaseLengthBy: half_length];
}
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = (unsigned int)([decompressed length] - strm.total_out);
// Inflate another chunk.
status = inflate (&strm, Z_SYNC_FLUSH);
if (status == Z_STREAM_END) {
done = YES;
} else if (status != Z_OK) {
break;
}
}
if (inflateEnd (&strm) != Z_OK) return nil;
// Set real length.
if (done) {
[decompressed setLength: strm.total_out];
return [NSData dataWithData: decompressed];
} else {
return nil;
}
}