最近学习WP8.1应用开发,想把C语言的SM3国密算法移植到手机app中。由于把C语言的代码转换成C#代码工作量较大,因此只能用winodws运行时组件来实现。

  SM3国密算法是一种HASH算法,具体详情请自行百度。

  结果测试发现手机上SM3算法计算出来的结果和电脑上运行的结果不同!经过我一点点调试发现是位移操作惹的祸,代码中有如下宏定义:

#define  SHL(x,n) (((x) & 0xFFFFFFFF) << n)
#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))

  第一行的宏定义当n大于32时,手机运算结果与电脑不同;第二行的宏定义当32-n小于0时,手机运算结果与电脑不同。

  为了更好地测试,我决定建一个干净的测试环境。首先新建一个C#语言的空白的windows phone应用项目,在xaml中放一个textblock和2个按钮

<Grid>
<StackPanel>
<TextBlock x:Name="txbResult"/>
<Button x:Name="btnCSharpLeft" Content="C#位移" Click="btnCSharpLeft_Click"></Button>
<Button x:Name="btnCLeft" Content="C左位移" Click="btnCLeft_Click"></Button>
</StackPanel>
</Grid>

再实现按钮点击事件

private void btnCSharpLeft_Click(object sender, RoutedEventArgs e)
{
txbResult.Text += "C#位移\n";
for (int i = ; i < ; i += )
{
string str = "0x12345678<<" + i.ToString() + "=" + (0x12345678 << i).ToString("X");
txbResult.Text += str.PadRight() + "0x12345678>>" + i.ToString() + "=" + (0x12345678 >> i).ToString("X") + "\n";
}
} private void btnCLeft_Click(object sender, RoutedEventArgs e)
{
txbResult.Text += "C位移\n";
Class1 c = new Class1();
for (int i = ; i < ; i += )
{
string str = "0x12345678<<" + i.ToString() + "=" + c.Func2(0x12345678, i).ToString("X");
txbResult.Text += str.PadRight() + "0x12345678>>" + i.ToString() + "=" + c.Func1(0x12345678, i).ToString("X") + "\n";
}
}

接着新建一个C++语言的windows运行时组件,对外提供两个函数,用以实现左位移和右位移

unsigned int Class1::Func1(unsigned int n, int b)
{
return n >> b;
} unsigned int Class1::Func2(unsigned int n, int b)
{
return n << b;
}

然后连上手机进行测试,我的手机是nokia920,公司测试部的测试机,先拿来用用,吼吼!

  可以看到C#的位移在超过32时是对32取模的,也就是说位移33位相当于位移1位,而手机上运行结果测试超过32位都是0!

为了确定是否C++语言的位移都是这么处理的,我再新建一个WIN32的控制台项目来测试

#include "stdio.h"

int main()
{
printf("C左移\n");
for (int i = ; i < ; i += )
{
printf("0x12345678<<%d = %x\n",i,0x12345678 << i);
}
printf("C右移\n");
for (int i = ; i < ; i += )
{
printf("0x12345678>>%d = %x\n", i, 0x12345678 >> i);
}
return ;
}

运行结果如下

可以看到和C#的结果是一样的。说明只有C++的windows运行时组件中才会有不同的结果。

同理我再测试位移负数位,比如 0x12345678>>-2,在C#和C++的WIN32程序中位移-2位相当于位移30位,而在C++的windows运行时组件中则结果是0。

结论:为了兼容性,位移时要对32取模,比如1>>n要写成1>>(n%32),这样在不同的平台中也能得到相同的结果。

WP8.1中C++的winodws运行时组件位移操作的差异的更多相关文章

  1. 报错:此版本的SQL Server Data Tools与此计算机中安装的数据库运行时组件不兼容

    在Visual Studio 2012中使用Entity Framework,根据模型生成数据库时,报如下错误: 无法在自定义编辑器中打开Transact-SQL文件此版本的SQL Server Da ...

  2. 为什么一定要调用 setlocale 呢? 因为在 C/C++ 语言标准中定义了其运行时的字符集环境为 "C" ,也就是 ASCII 字符集的一个子集。使用setlocal改变整个应用程序的字符集编码方式(wcstombs使用前要设置 setlocale (LC_ALL, "chs"); )

    setlocale 配置地域化信息. 语法: string setlocale(string category, string locale); 返回值: 字符串 函数种类: 操作系统与环境   内容 ...

  3. Windows 运行时组件

    Windows 运行时组件是自包含对象,可将其实例化,并可采用任一语言使用它,包括 C#.Visual Basic.JavaScript 和 C++. 你可以使用 Visual Studio 和 C# ...

  4. win7下无法安装QTP-少了Microsoft Visual c++2005 sp1运行时组件

    问题是:当我点击QTP的setup.exe进行QTP安装时,出现提示[少了Microsoft Visual c++2005 sp1运行时组件,安装时会提示命令行选项语法错误,键入“命令/?”可获取帮肋 ...

  5. Java中获取类的运行时结构

    获取运行时类的完整结构 通过反射获取运行时类的完整结构 Field(属性).Method(方法).Constructor(构造器).Superclass(父类).Interface(接口).Annot ...

  6. 用系统工具sxstrace检查缺少的VC运行时组件

    在管理员运行的命令提示符中输入sxstrace获得如下帮助: C:\>sxstrace WinSxs Tracing Utility. Usage: SxsTrace [Options] Opt ...

  7. vb 中recordset提示对象关闭时不允许操作

    vb中执行查询后,一般要判断是否为空,只要执行的查询执行了select,都可以用rs.eof 或者 rs.recordcount来判断, 但是,如果执行的sql中加了逻辑判断,导致没有执行任何sele ...

  8. 内核运行时数据结构的操作(启用路由功能),sysctl内核设置命令

    LINUX系统运行时,内核数据结构数据的修改,系统提供了统一抽象的文件操作接口(命名空间操作接口)比如启用路由功能echo  1 > proc/sys/net/ipv4/ip-forward// ...

  9. 安装LR11 时,安装Microsoft Visual c++2005 sp1运行时组件,就会提示命令行选项语法错误,键入“命令/?”可获取帮肋信息

    1.进入loadrunner-11\Additional Components\IDE Add-Ins\MS Visual Studio .NET 2.安装:LRVS2005IDEAddInSetup ...

随机推荐

  1. oracle基础知识

    -- 表 create table test (names varchar2(12),                    dates date,                    num    ...

  2. MongoDB Shard部署及Tag的使用

    Shard部署 准备测试环境 为准备数据文件夹 Cd  /home/tiansign/fanr/mongodb/Shard mkdir configdb1 configdb2 configdb3 mk ...

  3. 开窗函数 --over()

    一个学习性任务:每个人有不同次数的成绩,统计出每个人的最高成绩. 这个问题应该还是相对简单,其实就用聚合函数就好了. select id,name,max(score) from Student gr ...

  4. MySQL客户端工具 SQLyog

    我最喜欢它的History功能,把执行过的操作对应语句都输出出来,一些麻烦的语句用GUI操作后,还能保存对应的sql语句.不错! 官网:http://www.webyog.com 下面是官方的介绍:S ...

  5. 【函数】Oracle函数系列(2)--数学函数及日期函数

    [函数]Oracle函数系列(2)--数学函数及日期函数 1  BLOG文档结构图 2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不 ...

  6. DDL触发器的应用

    一般来说,DML触发器可以监测得到具体对象的具体数据的变更.然而,DDL触发器则能够对一些服务器的行为作出监控,比如我们可以利用DDL触发器来做登录限制啊,做一些日志控制啊之类的. 好,然后简单粗暴上 ...

  7. msysGit管理GitHub代码

    msysGit管理GitHub代码   代码的管理,在日常开发中是很重要的环节,程序员的修炼三部曲——版本控制,单元测试,项目自动化. 本篇就简单的说说通过msysGit来管理GitHub中的代码,实 ...

  8. 使用dwr时动态生成table的一个小技巧

    这篇随笔是我在07年写的,因为当时用了自己建设的blog,后来停止使用了,今天看到备份数据库还在,恢复出来放到这里.留着记录用. 我在使用DWR时,试了很多次都无法在动态生成的table中的一个或多个 ...

  9. Fiddler基本原理与抓取Andriod与IOS的App数据包

    Fiddler基本原理 Fiddler数据包的原理是Fiddler将自己设置为一个代理服务器,默认监听127.0.0.1:8888端口同时将浏览器的HTTP.HTTPS协议设置为使用代理服务器也就是使 ...

  10. PostgreSql常用脚本

    添加表字段 ALTER TABLE public.university ADD COLUMN "Province" character varying(10); COMMENT O ...