将十六进制的大NSString转换为十进制NSString iOS

时间:2016-11-19 10:58:08

标签: ios objective-c

正如问题的标题所述,我希望以十六进制数字取以下字符串:

b9c84ee012f4faa7a1e2115d5ca15893db816a2c4df45bb8ceda76aa90c1e096456663f2cc5e6748662470648dd663ebc80e151d4d940c98a0aa5401aca64663c13264b8123bcee4db98f53e8c5d0391a7078ae72e7520da1926aa31d18b2c68c8e88a65a5c221219ace37ae25feb54b7bd4a096b53b66edba053f4e42e64b63

并将其转换为十进制等效字符串:

130460875511427281888098224554274438589599458108116621315331564625526207150503189508290869993616666570545720782519885681004493227707439823316135825978491918446215631462717116534949960283082518139523879868865346440610923729433468564872249430429294675444577680464924109881111890440473667357213574597524163283811

我希望使用此代码,可在此link找到:

unsigned result = 0;
NSScanner *scanner = [NSScanner scannerWithString:hexString];

[scanner setScanLocation:1]; // bypass '#' character
[scanner scanHexInt:&result];
NSLog(@" %u",result);

但是,我一直得到以下结果:4294967295。关于如何解决这个问题的任何想法?

2 个答案:

答案 0 :(得分:1)

这听起来像是一个家庭作业/测验问题,而且不是为了编写代码,所以这里有一些暗示希望它们有所帮助。

您的号码是BIG,远远大于任何标准整数,因此您无法使用long long甚至NSDecimal执行此操作。

现在你可以去寻找一个“无限”的精确算术包,但是真正需要做的并不是那么难(但如果你要做的比这更多,那么使用包就行了)

现在回想一下你上学的日子,你是如何教导做基础转换的?标准方法是长除法和提醒。

示例:以十六进制的BAD开头并转换为十进制:

BAD ÷ A = 12A remainder 9
12A ÷ A =  1D remainder 8
 1D ÷ A =   2 remainder 9
  2 ÷ A =   0 remainder 2

现在读回余数,最后一个,给出2989十进制数。

长除法是一个时间过程中的一个数字,从最高位数开始,并在移动到下一个数字时携带余数。听起来像一个循环。

您的初始号码是一个字符串,最重要的数字是第一个。听起来像一个循环。

NSString逐个处理一个字符很痛苦。因此,首先将NSString转换为标准C字符串。如果将其复制到C阵列中,则可以在每次“分割”时覆盖它。您可能会发现标准C函数strlen()strcpy()很有帮助。

当然,你的字符串中有个字符,而不是整数值。在您的代码中加入ctype.h,然后使用digittoint()函数将数字中的每个字符转换为数字等效字符。

标准库没有digittoint()的反转,所以要将一个整数转换回它的等价字符,你需要编写自己的代码,想想索引到一个合适的常量字符串......

编写一个C函数,例如int divide(char *hexstring),它执行hexstring的一个长除法,将结果写入hexstring并返回余数。 (如果您希望编写更多通用代码,对测试很有用,请编写类似int divide(char *buf, int base, int divisor)的内容 - 这样您就可以将十六进制转换为十进制,然后再返回以检查是否返回到您开始的位置。

现在你可以循环调用你的divide并将余数(作为字符)累积到另一个字符串中。

结果字符串应该有多大?那么用十进制写的数字通常比用十六进制写的数字更多(例如2989 v.BAD)。如果你是通用的那么hex使用最少的数字,二进制使用最多。单个十六进制数字相当于4个二进制数字,因此工作缓冲区4倍的输入大小将始终足够长。 不要忘记允许在缓冲区中的C字符串中终止NUL

如上所述,为了测试使代码变通用,将十六进制字符串转换为十进制字符串,然后将其转换回十六进制字符串并检查结果与输入相同。

如果这听起来很复杂并不绝望,那么它只需要大约30行间隔良好的代码。

如果您遇到编码问题,请提出一个显示您的代码的新问题,解释出现了什么问题,并且有人无疑会帮助您。

HTH

答案 1 :(得分:0)

您的结果是unsinged int 32 bit(您正在使用的类型)的最大值。据我所知,NSScanner documentation long long是最受支持的类型。