关于缓存使用误区
memcache 和appfabric
缓存,大家都使用过,但不知道大家有没有碰到过什么问题. 以前在我们的porta项目,一开始是用企业库作为自己的缓存,但在后来中,我们发现那个缓存还是有很大问题.主要有3个方面
一是缓存大对象,我们一开时的缓存是把一个表里的所有东西查出来,然后再缓存的.同时也把很多不该缓存的东西都缓存进来,导致后面,每次加载缓存,都是非常慢. 而且也经常出现缓存丢失的现象.
二是,企业库的缓存是用了进程的内存来缓存的.因此没办法实现共享,尤其在f5负载均衡下,会出现从一台机跳到另外一台机的时候,缓存马上丢失了. 虽然这里我们后来通过配置F5,解决了这个问题.但不能共享缓存,依然会对我们的性能造成很大的影响.
三是,当时缓存对象那里我们也作了一定的封装,但没有实现基于接口的封装,所以后期我们要换其他缓存方案时,要大量更改代码.
所以最后,在我们架构优化的时候,我们决定用appfabric 作为我们的缓存服务器,同时所有组件都是基于接口编程的.
其实,刚开始我们也作了memcache 和appfabric进行了对比. 后来还是决定用appfabric作为我们的缓存服务.主要出自以下考虑.appfabric毕竟是微软Windows Azure的关键产品之一,它拥有高性能,高稳定性,功能强大. 再说我们定义的缓存组件是基于接口来定义的. 然后通过依赖注入来调用,所以当我们发现某个缓存组件不好用的时候,我们可以随时用其他cache方案来代替.
我们看重 appfabric,还看重如下几点.
1. 跟.net结合 更强.可以直接用来作session
2.可以作为orm的二级缓存.
NHibernate 和实体框架都可以使用 AppFabric 缓存作为二级缓存。Nhibernate 通过nhibernate.caches.velocity 来启用此功能(sourceforge.net/projects/nhcontrib/files/NHibernate.Caches/)。实体框架通过由 Jaroslaw Kowalski 提供的 EFCachingProvider 来启用此功能(code.msdn.microsoft.com/EFProviderWrappers)。
3.通过标签,来提高检索效率.
appfabric 可参考官网 http://msdn.microsoft.com/zh-cn/library/ee677312(v=azure.10).aspx
有关更多缓存使用误区,可参考.中文 http://kb.cnblogs.com/page/138696/ 英文http://www.codeproject.com/Articles/115107/Ten-Caching-Mistakes-that-Break-your-App
ACM题解报告——HD1006
今天解了一道杭电上的1006题:http://acm.hdu.edu.cn/showproblem.php?pid=1006
题目的大体意思就是讲,时钟上的时针、分针、秒针都想远离彼此,当三种针间的角度差都至少是给定的D角度时,称为happytime,最后需要输出一天内happytime所占的比例。解决该题的基本思想就是进行12小时即720分钟的happytime的暴力搜索,算出的总秒数除以720*60即最后的比例。
1、最开始拿到这个问题的时候,感觉有点无从下手,因为三种针每秒都在动着,我们可以选择一个标准,就是12时为0度,三种针的角速度都可以求出:时针:1/120 度/秒,分针:0.1 度/秒,秒针:6 度/秒,那么假使此刻为h时m分s秒,时针、分针、秒针的角度分别为30*h+0.5*m+1/120*s、6*m+0.1*s、6*s。
2、按照题目的意思,会给定一个角度D,而三种针两两之间的角度差必须要大于D,也就是解不等式
D<|angle|<360-D,分别解出不等式,再求它们之间的交集。
#include<stdio.h>
#include<stdlib.h>
/*h时m分s秒这一时刻的时针、分针、秒针的角度 */
#define hangle 30*h+0.5*m+1/120*s
#define mangle 6*m+0.1*s
#define sangle 6*s
/*三种针的转速*/
#define vh 1.0/120
#define vm 0.1
#define vs 6.0
int degree;
int s=0;
typedef struct //定义一个结构体用于储存不等式的解
{
double l;
double r;
}second;
second bargin(second a,second b)
{//函数bargin求交集
second c;
if(a.l>b.l )
c.l=a.l;
else
c.l=b.l;
if(a.r<b.r)
c.r=a.r;
else
c.r=b.r;
if(c.l>=c.r )
c.r=c.l=0;
return c;
}
second solve(double diff,double angle )
{//解不等式degree<|s*diff+angle|<360-degree
second ln;
if( diff>0 )
{
ln.l=(degree-angle)/diff;
ln.r=(360-degree-angle )/diff;
}
else
{
ln.l=(360-degree-angle )/diff;
ln.r=( degree-angle)/diff;
}
if( ln.l<0 )
ln.l=0;
if( ln.r>60 )
ln.r=60;
if( ln.r<=ln.l )
ln.r=ln.l=0;
return ln;
}
double happytime(int h,int m )
{
second ss[3][2];
double diff,angle;
second ln;
double result=0.0;
//hm 时针与分针之间满足happytime的秒数
diff=vh-vm;
angle=hangle-mangle;
ss[0][0]=solve( diff,angle );
ss[0][1]=solve( -diff,-angle );
//hs 时针与秒针之间满足happytime的秒数
diff=vh-vs;
angle=hangle-sangle;
ss[1][0]=solve( diff,angle );
ss[1][1]=solve(-diff,-angle );
//ms 分针与秒针之间满足happytime的秒数
diff=vm-vs;
angle=mangle-sangle;
ss[2][0]=solve( diff,angle );
ss[2][1]=solve(-diff,-angle );
int k,p,n;
/*注意下面这里的思想,绝对值不等式解出的区间要取并集,例如ss[0][0]与ss[0][1]间取并;而三个不同的表达式之间要取交集,即 ss[0][]与ss[1][]之间要取交集的 */
for( k=0;k<2;k++ )
for( p=0;p<2;p++ )
for( n=0;n<2;n++ )
{
ln=bargin( bargin(ss[0][k],ss[1][p]),ss[2][n] );
result+=( ln.r-ln.l );
}
return result;//返回每分钟内的happytime秒数
}
int main()
{
int h,m;
while(scanf("%ld",°ree)&°ree!=-1 )//输入-1结束
{
double result=0;
for(h=0;h<12;h++ )
for(m=0;m<60;m++ )
{
result+=happytime( h,m );
}
printf( "%.3lf\n",result*100.0/43200 );//最后的结果是输出比例
}
return 0;
}
杭电测试通过
从密码学角度看腾讯常用的TEA加密算法
免责声明:此文档的目的是为了分析腾讯常用的TEA算法,参考信息全部根据网上公开的资料,关键信息也做了过滤,不存在任何攻击和泄密。
TEA这个简单加密算法在中国如此有名,大概主要因为腾讯在大量协议,本地数据中使用这个算法。网上很多人甚至直接将腾讯的加密算法称为TEA算法。
腾讯的算法,数据分块的加密的确采用的是TEA(第一代)算法,密钥16个字节,每次处理的分块数据是8个字节(2个32位整数),但标准的TEA算法推荐处理的轮数是32轮甚至64轮,而腾讯使用的是16轮。应该是为了加快速度。
腾讯的加密算法,是于一个数据流(BUFFER)的处理,采用的的是改进CBC的算法(看见一片blog称这个是交织算法,很贴切)。你可以这样认为TEA这类对称加密算法是针ECB的(Electronic codebook),是处理一个定长的数据块的。但如果如果对于流数据只采用ECB算法是有巨大风险的,因为对称加密算法的本质是相同的原文和密钥,得到的密文肯定一致,如果对于流数据,单纯的分块处理,很容易让人伪造密文数据(维基上都有人针对某个图片做ECB预算,对比原图和加密后的图像,你仍然可以从密文图片上看出很多信息)。CBC算法对于这个问题的改造是在密文前面加入一个随机数生成的初始化向量IV(Initialization Vector),通过ECB算法得到的密文半成品要和前一个密文,(包括IV)进行异或预算预算得到密文,因为随机数每次都不一致。这样你可以认为密文是永远不会重复的,而且这样伪造的难度大大提升。另外CBC的算法是在ECB的基础上的,所以如果你的长度不足以填充一个块,会进行补齐。
下图来自维基
腾讯CBC算法的大致思路是,1个字节补齐长度 + N个补齐的字节(随机数填充)+M个字节的SALT(随机数)+ 数据内容+K个字节的校验0。补齐长度=TEA算法的块大小8 -(非补齐数据区长度模除 % 8),而非补齐数据区长度(1字节的补齐长度+数据内容长度+0校验长度之和)。对于解密的校验,在在解密后,检查K个0的校验字段都是0,可以认为在不知道密钥的情况下,进行伪造密文还是有不少麻烦。要说明的是这个算法的第一个BLOCK里面是可能有原文数据的,而其算法对于第一个BLOCK也进行了加密处理,这个和标准算法并不太一致(标准算法IV是无意义的),而且由于N可能为0,其加盐的处理是也是必须的。
先抛开加密算法的安全性不谈,吹毛求疵的说,这个实现在性能上的考虑有点欠缺。
首先这个算法没有考虑原文数据区字节对齐的问题,(假如补齐的长度是2)可能会导致原文的数据每次处理都不是在对齐位置,这多少会影响一些计算性能。
另外,TEA算法是针对2个4字节整数的算法,并没有规定字节序。而腾讯的实现为了考虑多平台的一致性,实现内部计算时都是使用网络序。这的确严谨一点,但考虑到代码99.99%的时候服务场景仍然是X86平台,而且X86的小头在整数转换上的优势,反而不如直接要求所有环境统一成小头字节序运算(就是要求在大头字节序的环境转换为小头字节序运算)。这样就避免了大部分时候转换网络序的消耗。
另外在每次异或的时候,是对每个字节进行的异或处理,上面的这些问题,稍微改进一下,提高20%的速度应该是有可能的。
最后还是YY一下这个算法的安全性,TEA算法其实足够满足大部分要求。虽然TEA是一个简单加密算法,腾讯使用的算法,早已被破解了,源代码也漫天飞了。但对称加密的最主要安全性在于每人不同的的动态密钥,不在算法本身,而且我们要搞明白加密算法主要用于网上的协议加密,存储数据的简单加密,他真正能防范的是第三方模拟,和中间点截获报文分析。而对于木马,不是加密算法对抗的范畴。形象的举例说密码学的应用范畴是二战潜伏在敌占区的英国特工向本土发报的报文处理,它能让德军截获电报时也无法破译,而木马是可能潜伏在发报员身边的德国间谍,对抗方法当然不一致。
参考资料:
《应用密码学》 当年密码学的红宝书,据说当年此书是管制书籍,禁止向我国出口,个人感觉翻译有点乱。
《密码编码学与网络安全》 这本书在一些细节上写的更清晰一些。
《维基:块密码的工作模式》 好文,强烈推荐。
《看雪论坛:RTX(腾讯通)本地保存密码TEA变形算法及还原器》 看算法的说明感觉根据DLL反出来的接口
《TEA和QQTEA》 这哥们应该也是通过反编译
pudn 上有很多是实现的源代码,比如QQTea,应该也是一些破解实现,但下载要收费。
【本文作者是fullsail(雁渡寒潭),本着自由的精神,你可以在无盈利的情况完整转载此文档,转载时请附上BLOG链接:http://www.cnblogs.com/fullsail,否则每字一元不讲价。对Baidu文库,360doc加价一倍】
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步