【问题标题】:Convert Large NSString in Hexadecimal to Decimal NSString iOS将十六进制的大 NSString 转换为十进制 NSString iOS
【发布时间】:2017-04-03 04:32:35
【问题描述】:

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

b9c84ee012f4faa7a1e2115d5ca15893db816a2c4df45bb8ceda76aa90c1e096456663f2cc5e6748662470648dd663ebc80e151d4d940c98a0aa5401aca64663c13264b8123bcee4db98f53e8c5d0391a7078ae72e7520da1926aa31d18b2c68c8e88a65a5c221219ace37ae25feb54b7bd4a096b53b66edba053f4e42e64b63

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

130460875511427281888098224554274438589599458108116621315331564625526207150503189508290869993616666570545720782519885681004493227707439823316135825978491918446215631462717116534949960283082518139523879868865346440610923729433468564872249430429294675444577680464924109881111890440473667357213574597524163283811

我希望使用此代码,在此 link

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

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

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

【问题讨论】:

  • 4294967295NSNotFound。这些值是如何相关的?通常十六进制的字符串是按字节组织的,但十六进制的b9 是十进制的 185。笔尖上的b11。如果它是二进制的,Int 就不能代表那个巨大的数字
  • 我不熟悉 RSA 密钥,但我想您需要先使用 openssl 解密密钥

标签: ios objective-c


【解决方案1】:

这听起来像是一个家庭作业/测验问题,所以并不是要编写代码,所以这里有一些提示,希望对他们有所帮助。

您的数字很大,远大于任何标准整数大小,因此您无法使用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)。如果您是一般人,那么十六进制使用最少的数字,而二进制使用最多。一个十六进制数字等于 4 个二进制数字,因此 4 倍输入大小的工作缓冲区总是足够长的。 不要忘记在缓冲区的 C 字符串中允许终止 NUL

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

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

如果您在编码时遇到困难,它会提出一个新问题来显示您的代码,解释哪里出了问题,毫无疑问有人会帮助您。

HTH

【讨论】:

  • 惊人的学术答案!它有算法背景,甚至对最终解决方案的风格提出了一些建议。
【解决方案2】:

您的结果是unsinged int 32 位的最大值,即您正在使用的类型。据我所知,NSScanner documentationlong long 是最大支持的类型。

【讨论】:

  • 我试过这段代码,我现在得到的答案是 9
猜你喜欢
  • 2012-06-16
  • 2011-05-15
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
  • 2012-06-04
  • 2011-09-04
  • 2011-11-02
相关资源
最近更新 更多