QNHex.m 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //
  2. // QNHex.m
  3. // HappyDNS
  4. //
  5. // Created by bailong on 15/7/31.
  6. // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
  7. //
  8. #import "QNHex.h"
  9. static char DIGITS_LOWER[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
  10. static char DIGITS_UPPER[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  11. static int hexDigit(char c) {
  12. int result = -1;
  13. if ('0' <= c && c <= '9') {
  14. result = c - '0';
  15. } else if ('a' <= c && c <= 'f') {
  16. result = 10 + (c - 'a');
  17. } else if ('A' <= c && c <= 'F') {
  18. result = 10 + (c - 'A');
  19. }
  20. return result;
  21. }
  22. static char *decodeHex(const char *data, int size) {
  23. if ((size & 0x01) != 0) {
  24. return NULL;
  25. }
  26. char *output = malloc(size / 2);
  27. int outLimit = 0;
  28. for (int i = 0, j = 0; j < size; i++) {
  29. int f = hexDigit(data[j]);
  30. if (f < 0) {
  31. outLimit = 1;
  32. break;
  33. }
  34. j++;
  35. int f2 = hexDigit(data[j]);
  36. if (f2 < 0) {
  37. outLimit = 1;
  38. break;
  39. }
  40. f = (f << 4) | f2;
  41. j++;
  42. output[i] = (char)(f & 0xff);
  43. }
  44. if (outLimit) {
  45. free(output);
  46. return NULL;
  47. }
  48. return output;
  49. }
  50. static char *encodeHexInternal(char *output_buf, const char *data, int size, char hexTable[]) {
  51. for (int i = 0, j = 0; i < size; i++) {
  52. output_buf[j++] = hexTable[((0XF0 & data[i]) >> 4) & 0X0F];
  53. output_buf[j++] = hexTable[((0X0F & data[i])) & 0X0F];
  54. }
  55. return output_buf;
  56. }
  57. static char *encodeHex(const char *data, int size, char hexTable[]) {
  58. char *output = malloc(size * 2);
  59. return encodeHexInternal(output, data, size, hexTable);
  60. }
  61. char *qn_encodeHexData(char *buff, const char *data, int data_size, BOOL up) {
  62. char *hexTable = DIGITS_UPPER;
  63. if (!up) {
  64. hexTable = DIGITS_LOWER;
  65. }
  66. return encodeHexInternal(buff, data, data_size, hexTable);
  67. }
  68. @implementation QNHex
  69. + (NSString *)encodeHexData:(NSData *)data {
  70. char *e = encodeHex(data.bytes, (int)data.length, DIGITS_UPPER);
  71. NSString *str = [[NSString alloc] initWithBytes:e length:data.length * 2 encoding:NSASCIIStringEncoding];
  72. free(e);
  73. return str;
  74. }
  75. + (NSString *)encodeHexString:(NSString *)str {
  76. return [QNHex encodeHexData:[str dataUsingEncoding:NSUTF8StringEncoding]];
  77. }
  78. + (NSData *)decodeHexString:(NSString *)hex {
  79. char *d = decodeHex(hex.UTF8String, (int)hex.length);
  80. if (d == NULL) {
  81. return nil;
  82. }
  83. NSData *data = [NSData dataWithBytes:d length:hex.length / 2];
  84. free(d);
  85. return data;
  86. }
  87. + (NSString *)decodeHexToString:(NSString *)hex {
  88. NSData *data = [QNHex decodeHexString:hex];
  89. if (data == nil) {
  90. return nil;
  91. }
  92. return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  93. }
  94. @end