我如何解压缩一个用 zlib 压缩的 NSString
How do I decompress an NSString I have that was compressed with zlib
我有一个 NSString
(例如 eNoLycgsVgChvILSEoWS1IoSPQBFZgb4
),它是我从 Web 服务器获得的,它只是使用 zlib
压缩的普通字符串。我如何在 Objective-C 中解压它?我找到了一些库,但它们只接受完整文件,而不是简单的字符串。
好的,根据上面的内容,您似乎并不真正知道格式是什么 - 但它似乎是 ZLib deflate
,Base64 编码。无耻地抄袭其他 Whosebug 答案,这里有一段代码可以解压缩您的数据:
#import <Foundation/Foundation.h>
#import <zlib.h>
int main( int argc, const char * argv[] )
{
@autoreleasepool
{
NSLog( @"Starting..." );
NSString * base64String = @"eJwLycgsVgChvILSEoWS1IoSPQBFZgb4";
NSData * compressedData = [ [ NSData alloc ] initWithBase64EncodedString: base64String options: 0 ];
NSUInteger full_length = [ compressedData length ];
NSUInteger half_length = [ compressedData length ] / 2;
NSMutableData * decompressedData = [ 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 ) full_length;
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if ( inflateInit2( &strm, ( 15 + 32 ) ) != Z_OK )
{
NSLog( @"Could not initialise ZLib" );
return EXIT_FAILURE;
}
while ( done == NO )
{
// Make sure we have enough room and reset the lengths.
if ( strm.total_out >= [ decompressedData length ] )
{
[ decompressedData increaseLengthBy: half_length ];
}
strm.next_out = [ decompressedData mutableBytes ] + strm.total_out;
strm.avail_out = ( unsigned int )( [ decompressedData 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( @"Decompression failed with status %i", status );
break;
}
}
if ( inflateEnd( &strm ) != Z_OK )
{
NSLog( @"Could not complete decompression" );
return EXIT_FAILURE;
}
// Set real length.
if ( done )
{
[ decompressedData setLength: strm.total_out ];
NSString * string = [ [ NSString alloc ] initWithData: decompressedData
encoding: NSUTF8StringEncoding ];
NSLog( @"String: %@", string );
}
else
{
return EXIT_FAILURE;
}
}
NSLog( @"...Success" );
return EXIT_SUCCESS;
}
当 运行 时,打印如下内容:
2016-06-16 12:40:14.454 Objective Z[82569:7532295] Starting...
2016-06-16 12:40:14.455 Objective Z[82569:7532295] String: This is input text.
2016-06-16 12:40:14.455 Objective Z[82569:7532295] ...Success
Program ended with exit code: 0
您需要确保 link 反对 ZLib。在 XCode 中项目的构建阶段部分,在 "Link Binary With Libraries" 下,“+”按钮提供了一个可搜索的弹出窗口;寻找 "libz"。这可能不会出现在 iOS 上;它存在于 OS X SDK 中;这超出了这个答案的范围,如果您遇到问题,Google 无疑会迅速给出答案。
我有一个 NSString
(例如 eNoLycgsVgChvILSEoWS1IoSPQBFZgb4
),它是我从 Web 服务器获得的,它只是使用 zlib
压缩的普通字符串。我如何在 Objective-C 中解压它?我找到了一些库,但它们只接受完整文件,而不是简单的字符串。
好的,根据上面的内容,您似乎并不真正知道格式是什么 - 但它似乎是 ZLib deflate
,Base64 编码。无耻地抄袭其他 Whosebug 答案,这里有一段代码可以解压缩您的数据:
#import <Foundation/Foundation.h>
#import <zlib.h>
int main( int argc, const char * argv[] )
{
@autoreleasepool
{
NSLog( @"Starting..." );
NSString * base64String = @"eJwLycgsVgChvILSEoWS1IoSPQBFZgb4";
NSData * compressedData = [ [ NSData alloc ] initWithBase64EncodedString: base64String options: 0 ];
NSUInteger full_length = [ compressedData length ];
NSUInteger half_length = [ compressedData length ] / 2;
NSMutableData * decompressedData = [ 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 ) full_length;
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if ( inflateInit2( &strm, ( 15 + 32 ) ) != Z_OK )
{
NSLog( @"Could not initialise ZLib" );
return EXIT_FAILURE;
}
while ( done == NO )
{
// Make sure we have enough room and reset the lengths.
if ( strm.total_out >= [ decompressedData length ] )
{
[ decompressedData increaseLengthBy: half_length ];
}
strm.next_out = [ decompressedData mutableBytes ] + strm.total_out;
strm.avail_out = ( unsigned int )( [ decompressedData 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( @"Decompression failed with status %i", status );
break;
}
}
if ( inflateEnd( &strm ) != Z_OK )
{
NSLog( @"Could not complete decompression" );
return EXIT_FAILURE;
}
// Set real length.
if ( done )
{
[ decompressedData setLength: strm.total_out ];
NSString * string = [ [ NSString alloc ] initWithData: decompressedData
encoding: NSUTF8StringEncoding ];
NSLog( @"String: %@", string );
}
else
{
return EXIT_FAILURE;
}
}
NSLog( @"...Success" );
return EXIT_SUCCESS;
}
当 运行 时,打印如下内容:
2016-06-16 12:40:14.454 Objective Z[82569:7532295] Starting...
2016-06-16 12:40:14.455 Objective Z[82569:7532295] String: This is input text.
2016-06-16 12:40:14.455 Objective Z[82569:7532295] ...Success
Program ended with exit code: 0
您需要确保 link 反对 ZLib。在 XCode 中项目的构建阶段部分,在 "Link Binary With Libraries" 下,“+”按钮提供了一个可搜索的弹出窗口;寻找 "libz"。这可能不会出现在 iOS 上;它存在于 OS X SDK 中;这超出了这个答案的范围,如果您遇到问题,Google 无疑会迅速给出答案。