最近在整理《0bug-C/C++商用工程之道》一书的勘误表,对其中P199页的随机数描述,自己觉得不太满意,有点描述不清,因此做了一点修订。
2 获得0
如上所示,如果我们期待一个经过某种计算获得的绝对0值,也通常使用下面的方法产生。
inline int _Get0(void)
{
int nRet=rand();
return nRet^nRet; //以异或方式求的0
}
此处读者可能会觉得奇怪,我们明明可以以一个1带代表非零值,以0代表0值,为什么还要多此一举,做两个函数。
这里笔者解释一下:做这两个函数的目的,主要是为了某些时候商用加密需求,全局收拢所有的非0值0值的服务请求,提供高强度加密的可能。比如我们看看如下段落:
for(i=0;i<n;i++){}
我们可以写为:
for(i=_Get(0);i<n;i++){}
又或者
while(1)
我们可以写为
while(_GetNot0())
此时,我们可以在这两个函数中,根据加密条件做一定的数学变幻,使之从绝对正确,变得部分不正确,由于这是几乎所有循环计算的基数产生器,并且使用inline做内联展开,我们可以瞬间将加密要点部署到程序的每个角落,起到软件保护的作用。
5.5.5.3 获得给定范围的随机数
其实C语言里面,已经针对随机数提供了大量的函数,本来已经可以很方便的调用。不过在工程实践中,笔者发现团队里很多程序员,居然很多时候用错了随机数,造成一些不该有的错误,因此,把随机数的获得函数,也做了标准化封装。
(注意,nBegin和nEnd所限定的范围区间,不能大于编译器约定的随机数最大范围)
//获得给定区间内的随机数
inline int GetRandomBetween(int nBegin,int nEnd)
{
int n=_GetNot0(); //获得一个随机数
int nBetween=0;
if(0>nBegin) nBegin=-nBegin; //防御性设计防止Begin为负值
if(0>nEnd) nEnd=-nEnd; //防御性设计防止End为负值
if(nBegin>nEnd) //调整Begin和End的顺序,保证End>Begin
{
nBetween=nEnd;
nEnd=nBegin;
nBegin=nBetween;
}
else if(nBegin==nEnd) //如果给定的Beggin和End相等,即范围为0
{
return nBegin; //如果范围区间为0,直接返回
}
nBetween=nEnd-nBegin; //求的区间
n=n%nBetween; //通过求余运算限幅
n+=nBegin; //与Begin累加,确保结果落于Begin和End之间
return n;
}
本文转自tonyxiaohome 51CTO博客,原文链接:http://blog.51cto.com/tonyxiaohome/338233,如需转载请自行联系原作者