9

I have a piece of code in vb. I need to convert array of bytes to base 64 string. Following is the vb code.

If arrLicence.Count > 0 Then

LicenceBytes = CType(Array.CreateInstance(GetType(Byte),6), Byte())

        LicenceBytes(0) = Convert.ToByte(arrLicence(0).ToString(), 16)
        LicenceBytes(1) = Convert.ToByte(arrLicence(1).ToString(), 16)
        LicenceBytes(2) = Convert.ToByte(arrLicence(2).ToString(), 16) 
        LicenceBytes(3) = Convert.ToByte(arrLicence(3).ToString(), 16) 
        LicenceBytes(4) = Convert.ToByte(arrLicence(4).ToString(), 16)
        LicenceBytes(5) = Convert.ToByte(arrLicence(5).ToString(), 16)

        LicenceString = Convert.ToBase64String(LicenceBytes) '6 byteArray - passed by the user - Base64Encoded

I need its equivalent in iphone. I tried with NSData and base64 conversion but result defers.

I have used this link for conversion. http://www.cocoadev.com/index.pl?BaseSixtyFour

I tried by creating individual bytes using memcpy and then creating an array but with no success.

What I have tried is as follows:

NSData *d1 =[@"64" dataUsingEncoding:NSUTF16StringEncoding];
NSData *d2 = [@"37" dataUsingEncoding:NSUTF16StringEncoding];
NSData *d3 = [@"81" dataUsingEncoding:NSUTF16StringEncoding];
NSData *d4 = [@"d4" dataUsingEncoding:NSUTF16StringEncoding];

unsigned char *buffer = (unsigned char*)malloc(8);
buffer[0] =  [d1 bytes]  ;
buffer[1] =  [d2 bytes] ;
buffer[2] =  [d3 bytes] ;
buffer[3] =  [d4 bytes] ;

NSData *data = [NSData dataWithBytes:buffer length:4];

NSString *str = [self encodeBase64WithData:data];
free(buffer);

This results in IJCgkA== while code in .NET returns ZDeB1A==

Please note that the conversion is for first four bytes of arrLicence and the input is 64, 37, 81, d4

Community
  • 1
  • 1
DivineDesert
  • 6,924
  • 1
  • 29
  • 61
  • Building the byte array in an NSData or NSMutableData and then using code like [this](http://stackoverflow.com/questions/392464/any-base64-library-on-iphone-sdk/4727124#4727124) is the way to go. If you share what you have actually tried, perhaps someone can point out where you went wrong. – Anomie Jun 27 '11 at 11:24

6 Answers6

4

Try this one, i hope this will surely help you. get-base64-nsstring-from-nsdata

Community
  • 1
  • 1
4
unsigned char *buffer = (unsigned char*)malloc(8);
buffer[0] =  [d1 bytes]  ;
buffer[1] =  [d2 bytes] ;
buffer[2] =  [d3 bytes] ;
buffer[3] =  [d4 bytes] ;

Not sure what you expect this to do. bytes return an array, and you are assigning the addresses of the arrays to char elements of your buffer. This buffer won't be filled with any of the data you expect, and the "data" from d2 will partially overwrite those from d1 etc.

Also, you shouldn't make much assumptions about the lengths of your byte arrays, especially not if using UTF-16.

In a word: You don't throw the data you expect at your conversion routine. Maybe check that in the debugger.

Eiko
  • 25,601
  • 15
  • 56
  • 71
3

See code sample, Very self-explained ...

http://www.cocoadev.com/index.pl?BaseSixtyFour

Also check below SO post .

How do I do base64 encoding on iphone-sdk?

Community
  • 1
  • 1
Jhaliya - Praveen Sharma
  • 31,697
  • 9
  • 72
  • 76
  • Sorry I forgot to mention that I have used these links to convert string to base64. Here arrays are being converted to base 64 so I am not getting desired output :( – DivineDesert Jun 24 '11 at 10:10
  • @Dimple Panchal:I suspect conversion issues anyway. Could u elaborate your process ? – Jhaliya - Praveen Sharma Jun 24 '11 at 10:13
  • In my code each code is converted to Bytes and then the entire byte array is converted to base 64 string. I tried converting individual string to base64 and then append it, but Its not working :( – DivineDesert Jun 24 '11 at 10:17
2
//strBusiCode = @"64-37-81-d4-39-6d";
NSArray *tmp_arr = [strBusiCode componentsSeparatedByString:@"-"];
NSMutableData *commandToSend= [[NSMutableData alloc] init];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int i;
for (i=0; i < [tmp_arr count]; i++) {
    byte_chars[0] = [[tmp_arr objectAtIndex:i] characterAtIndex:0];
    byte_chars[1] = [[tmp_arr objectAtIndex:i] characterAtIndex:1];
    whole_byte = strtol(byte_chars, NULL, 16);
    [commandToSend appendBytes:&whole_byte length:1]; 
}
return commandToSend;

This commandToSend is then converted to base64 data.

DivineDesert
  • 6,924
  • 1
  • 29
  • 61
0

You can use this base64.h and base64.m class to decode to base64 string.

base64.h

#import <Foundation/Foundation.h>

@interface NSData (Base64) 

+ (NSData *)dataWithBase64EncodedString:(NSString *)string;
- (id)initWithBase64EncodedString:(NSString *)string;

- (NSString *) base64Encoding;
- (NSString *) base64EncodingWithLineLength:(unsigned int) lineLength;

@end

base64.m

#import "base64.h"

static char encodingTable[64] = {
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
    'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
    'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' };

@implementation NSData (VQBase64)

- (id)initWithString:(NSString *)string {
    if (self = [super init]) {
        [self initWithBase64EncodedString:string];
    }
    return self;

}


+ (NSData *) dataWithBase64EncodedString:(NSString *) string {
    return [[[NSData allocWithZone:nil] initWithBase64EncodedString:string] autorelease];
}

- (id) initWithBase64EncodedString:(NSString *) string {
    NSMutableData *mutableData = nil;

    if( string ) {
        unsigned long ixtext = 0;
        unsigned long lentext = 0;
        unsigned char ch = 0;
        unsigned char inbuf[4], outbuf[3];
        short i = 0, ixinbuf = 0;
        BOOL flignore = NO;
        BOOL flendtext = NO;
        NSData *base64Data = nil;
        const unsigned char *base64Bytes = nil;

        // Convert the string to ASCII data.
        base64Data = [string dataUsingEncoding:NSASCIIStringEncoding];
        base64Bytes = [base64Data bytes];
        mutableData = [NSMutableData dataWithCapacity:[base64Data length]];
        lentext = [base64Data length];

        while( YES ) {
            if( ixtext >= lentext ) break;
            ch = base64Bytes[ixtext++];
            flignore = NO;

            if( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ch = ch - 'A';
            else if( ( ch >= 'a' ) && ( ch <= 'z' ) ) ch = ch - 'a' + 26;
            else if( ( ch >= '0' ) && ( ch <= '9' ) ) ch = ch - '0' + 52;
            else if( ch == '+' ) ch = 62;
            else if( ch == '=' ) flendtext = YES;
            else if( ch == '/' ) ch = 63;
            else flignore = YES;

            if( ! flignore ) {
                short ctcharsinbuf = 3;
                BOOL flbreak = NO;

                if( flendtext ) {
                    if( ! ixinbuf ) break;
                    if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1;
                    else ctcharsinbuf = 2;
                    ixinbuf = 3;
                    flbreak = YES;
                }

                inbuf [ixinbuf++] = ch;

                if( ixinbuf == 4 ) {
                    ixinbuf = 0;
                    outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 );
                    outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 );
                    outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F );

                    for( i = 0; i < ctcharsinbuf; i++ )
                        [mutableData appendBytes:&outbuf[i] length:1];
                }

                if( flbreak )  break;
            }
        }
    }

    self = [self initWithData:mutableData];
    return self;
}

- (NSString *) base64Encoding {
    return [self base64EncodingWithLineLength:0];
}

- (NSString *) base64EncodingWithLineLength:(unsigned int) lineLength {
    const unsigned char     *bytes = [self bytes];
    NSMutableString *result = [NSMutableString stringWithCapacity:[self length]];
    unsigned long ixtext = 0;
    unsigned long lentext = [self length];
    long ctremaining = 0;
    unsigned char inbuf[3], outbuf[4];
    unsigned short i = 0;
    unsigned short charsonline = 0, ctcopy = 0;
    unsigned long ix = 0;

    while( YES ) {
        ctremaining = lentext - ixtext;
        if( ctremaining <= 0 ) break;

        for( i = 0; i < 3; i++ ) {
            ix = ixtext + i;
            if( ix < lentext ) inbuf[i] = bytes[ix];
            else inbuf [i] = 0;
        }

        outbuf [0] = (inbuf [0] & 0xFC) >> 2;
        outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
        outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
        outbuf [3] = inbuf [2] & 0x3F;
        ctcopy = 4;

        switch( ctremaining ) {
            case 1:
                ctcopy = 2;
                break;
            case 2:
                ctcopy = 3;
                break;
        }

        for( i = 0; i < ctcopy; i++ )
            [result appendFormat:@"%c", encodingTable[outbuf[i]]];

        for( i = ctcopy; i < 4; i++ )
            [result appendString:@"="];

        ixtext += 3;
        charsonline += 4;

        if( lineLength > 0 ) {
            if( charsonline >= lineLength ) {
                charsonline = 0;
                [result appendString:@"\n"];
            }
        }
    }

    return [NSString stringWithString:result];
}

@end

Please check and let me know if any issue.

AppAspect
  • 4,461
  • 2
  • 30
  • 46
0

If you look at the 2 last numbers you give as example, you will notice conversion match. Because the hi and low parts are the same.

Just swap the hi and low words.

Moose
  • 2,607
  • 24
  • 23
  • And I don't really see the poin about all that code on this page ! ;-) – Moose Jul 03 '11 at 11:26
  • Sorry guys, the 'Tripper' badge should exist, at least for me.. Using the OpenSSL is a possible options http://www.x2on.de/2010/12/16/tutorial-script-for-building-openssl-for-ios-iphoneipad/ Then you can use the BIO functions to encode or decode 64bits, among other usefull things.. – Moose Jul 05 '11 at 01:20