ASCII para nsdata
-
28-09-2019 - |
Pergunta
Esta é outra rachadura no meu problema no MD5. Eu sei que o problema é com o caractere ASCII © (0XA9, 169). Ou é a maneira como estou inserindo o personagem na string ou é um problema de bytes mais alto versus menor.
Se eu
NSString *source = [NSString stringWithFormat:@"%c", 0xa9];
NSData *data = [source dataUsingEncoding:NSASCIIStringEncoding];
NSLog(@"\n\n ############### source %@ \ndata desc %@", source, [data description]);
CC_MD5([data bytes], [data length], result);
return [NSString stringWithFormat:
@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
Resultado:
######## ©Descrição dos dados] = (nulo)
MD5: D41D8CD98F00B204E9800998ECF8427E
Valores: int 169 char ©
Quando eu mudo a codificação para
NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source length]];
O resultado é
######## ©Descrição dos dados] = "<" C2>
MD5: 6465DAD1D31752BE3F3283E8F70FEEF7
Quando eu mudo a codificação para
NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
O resultado é ###############om © len 2 [descrição dos dados] = "<" c2a9>
MD5: A541ECDA3D4C67F1151CAD5075633423
Quando eu executo a mesma função em java, eu recebo
">>>>> msg ## 251 251
MD5 A252C2C85A9E7756D5BA5DA9949D57ED
A questão é qual é a melhor maneira de obter o mesmo byte no OBJC que eu entro em Java?
Solução 2
Graças à explicação de Gbegan em outro post, pude reunir isso.
for(int c = 0; c < [s length]; c++){
int number = [s characterAtIndex:c];
unsigned char c[1];
c[0] = (unsigned char)number;
NSMutableData *oneByte = [NSMutableData dataWithBytes:&c length:1];
}
Outras dicas
"ASCII para nsdata" não faz sentido, porque o ASCII é uma codificação; Se você codificou caracteres, você tem dados.
Uma codificação é uma transformação de caracteres unicode ideais (pontos de código) em unidades de um ou mais bytes (unidades de código), possivelmente em seqüências como os pares substitutos do UTF-16.
Uma NSString é mais ou menos um objeto Unicode ideal. Contém o personagens da string, no unicode, independentemente de qualquer codificação*.
ASCII é uma codificação. UTF-8 também é uma codificação. Quando você pede sua string por sua UTF8String
, você está pedindo para codificar seus personagens como UTF-8.
NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source length]];
O resultado é
######### source © [data description] = "<"c2>
Isso porque você passou pelo comprimento errado. O comprimento da string (em caracteres) não é o mesmo que o número de unidades de código (bytes, neste caso) em algumas codificações.
O comprimento correto é strlen([source UTF8String])
, mas é mais fácil para você e mais rápido no tempo de execução usar dataUsingEncoding:
pedir à string para criar o objeto nsdata para você.
Quando eu mudo a codificação para
NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
Você não mudou a codificação. Você ainda está codificando isso como UTF-8.
Usar dataUsingEncoding:
.
A questão é qual é a melhor maneira de obter o mesmo byte no OBJC que eu entro em Java?
Use a mesma codificação.
Não existe "ASCII estendido". Existem várias codificações diferentes baseadas em (ou pelo menos compatíveis com) ASCII, incluindo ISO 8859-1, ISO 8859-9, MacRoman, Windows CodEpage 1252 e UTF-8. Você precisa decidir qual você quer dizer e dizer à string para codificar seus personagens com isso.
Melhor ainda, continue usando o UTF-8-é quase sempre a escolha certa para o texto principalmente-ASCII-e altere seu código Java.
NSData *data = [source dataUsingEncoding:NSASCIIStringEncoding];
Resultado:
[data description] = (null)
O True ASCII pode codificar apenas 128 caracteres possíveis. O Unicode inclui todos os ASCII inalterados, portanto, os primeiros 128 pontos de código no Unicode são o que o ASCII pode codificar. Qualquer outra coisa, ascii não pode codificar.
eu tenho visto NSASCIIStringEncoding
se comportar como equivalente a NSISOLatin1StringEncoding
antes da; Parece que eles podem ter mudado para ser uma codificação ASCII pura, e se for esse o caso, isso é uma coisa boa. Não há símbolo de direitos autorais no ASCII. O que você vê aqui é o resultado correto.
*Isso não é bem verdade; Os caracteres são expostos como UTF-16; portanto, quaisquer caracteres fora do plano multilíngue básico são expostos como pares substitutos, não de caracteres inteiros, como estariam em um objeto de string verdadeiramente ideal. Esta é uma troca. No Swift, o tipo de string integrado é um objeto Unicode ideal perfeito; Os personagens são personagens, nunca divididos até a codificação. Mas, ao trabalhar com a NSString (seja em Swift ou em Objective-C), no que diz respeito a você, você deve tratá-lo como uma corda ideal.