NSString+Hex.m 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // _____ _
  2. // |_ _| |_ _ _ ___ ___ _ __ __ _
  3. // | | | ' \| '_/ -_) -_) ' \/ _` |_
  4. // |_| |_||_|_| \___\___|_|_|_\__,_(_)
  5. //
  6. // Threema iOS Client
  7. // Copyright (c) 2012-2020 Threema GmbH
  8. //
  9. // This program is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU Affero General Public License, version 3,
  11. // as published by the Free Software Foundation.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU Affero General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Affero General Public License
  19. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. #import "NSString+Hex.h"
  21. #import <stdio.h>
  22. #import <stdlib.h>
  23. #import <string.h>
  24. @implementation NSString (Hex)
  25. + (NSString*)stringWithHexData:(NSData*)data {
  26. unsigned char *c = (unsigned char*)data.bytes;
  27. if (c == nil)
  28. return nil;
  29. NSUInteger n = data.length;
  30. NSMutableString* s = [NSMutableString stringWithCapacity:(2 * n)];
  31. for (NSUInteger i = 0; i < n; i++) {
  32. [s appendFormat:@"%02x", c[i]];
  33. }
  34. return s;
  35. }
  36. - (NSData*)decodeHex
  37. {
  38. const char *hexChars = [self cStringUsingEncoding:NSASCIIStringEncoding];
  39. if (hexChars == NULL)
  40. return nil;
  41. NSUInteger length = strlen(hexChars);
  42. unsigned char *bytes = malloc(length / 2);
  43. unsigned char lastnib = 0xff;
  44. NSUInteger n = 0;
  45. NSUInteger i;
  46. for (i = 0; hexChars[i] != 0; i++) {
  47. unsigned char curhex = hexChars[i];
  48. unsigned char curnib;
  49. if (curhex >= '0' && curhex <= '9')
  50. curnib = curhex - '0';
  51. else if (curhex >= 'a' && curhex <= 'f')
  52. curnib = curhex - 'a' + 0x0a;
  53. else if (curhex >= 'A' && curhex <= 'F')
  54. curnib = curhex - 'A' + 0x0a;
  55. else
  56. continue; /* ignore unknown character */
  57. if (lastnib != 0xff) {
  58. /* we have another full byte */
  59. bytes[n] = (lastnib << 4) | curnib;
  60. n++;
  61. lastnib = 0xff;
  62. } else {
  63. lastnib = curnib;
  64. }
  65. }
  66. return [NSData dataWithBytesNoCopy:bytes length:n];
  67. }
  68. @end