Math 函数生成随时间随机递增的数字
我试图伪造Math 函数生成随时间随机递增的数字,math,random,Math,Random,我试图伪造下载计数。它应该随时间随机增加。一些下载计数模式会更好 在不使用数据库或不在任何地方存储计数器的情况下,这是可能的吗 我的想法是检查我的应用程序发布后经过的秒数。然后把它放到一个公式中,这个公式会显示出虚假的下载数量。用户可以随时请求查看下载计数 是否有随机递增的数学函数?我可以把我的第二个span>/code>传递到那里,然后按我喜欢的方式缩放它 类似这样的内容:getDownloadCount(secondsPassed) 编辑:下面是一个示例解决方案。但随着时间的推移,它的性能
下载计数
。它应该随时间随机增加。一些下载计数模式会更好
在不使用数据库或不在任何地方存储计数器的情况下,这是可能的吗
我的想法是检查我的应用程序发布后经过的秒数。然后把它放到一个公式中,这个公式会显示出虚假的下载数量。用户可以随时请求查看下载计数
是否有随机递增的数学函数?我可以把我的第二个span>/code>传递到那里,然后按我喜欢的方式缩放它
类似这样的内容:getDownloadCount(secondsPassed)
编辑:下面是一个示例解决方案。但随着时间的推移,它的性能越来越差
downloadCount = 0
loop secondsPassed/60 times // Loop one more time for every minute passed
downloadCount += seededRandom(0, 10)
对于某些确定性函数(可能是f(x)=x
,或者如果你的假应用程序真的很棒f(x)=2^x
),以及一个随机函数r
,它输出的随机数有时是负数,有时是正数
您的绘图功能g
可以是:
g(x)=f(x)+r
编辑
这个怎么样:您可以使用Unix时间戳。比如:
Downloads = constant + ( unix time / another constant )
您可以改变这两个常量以获得一个合理的数字
附言:如果你想要一个线性函数,否则你可以:
Downloads = (unix time) ^ constant
依此类推。您正在查找一个序列,该序列总是随机增加,这取决于您上次请求该序列的时间长短
这可以通过一个随机序列来完成,该随机序列总是以相同的方式播种
然后我们每次迭代相同的序列以得到图
我们需要一个增加计数器、存储新时间和计数并返回计数的函数
理想情况下,我们可以将增长建模为泊松过程,但这里可以用线性过程
class Counter {
private static int counter = 0;
private static int time = 0;
private static double rate = 5.0;
private Random r;
public Counter(int seed){
counter = 0;
r = new Random(seed);
}
private int poisson(double rate, int diff){
// We're gonna cheat here and sample uniformly
return r.Next(0, (int)Math.Round(rate * diff));
}
public int getNext(int t){
var diff = t - time;
time = t;
if (diff <= 0) return counter;
counter += this.poisson(rate, diff);
return counter;
}
}
void Main()
{
var c = new Counter(1024);
for(var i = 0; i< 10; i++){
Console.WriteLine(String.Format("||{0}\t|{1}\t||",i,c.getNext(i)));
}
}
它不是“随机”的,但是你可以使用A*(X/B+SIN(X/B))
(按一些数字缩放)来引入一些噪声。您可以调整A和B以更改结果的比例以及“噪波”循环的频率
实际上,任何一阶导数在一定范围内的周期函数都可以工作。伪造下载计数听起来不是一件好事。然而,在设计安全通信协议时,存在着单调增长函数的合理用例,这些函数的值具有一定的随机性
我假设你有:
- 作为单调增长函数给出的增长模型,为所需函数提供近似值
- 访问时间戳,该时间戳从不减少
- 存储常量随机种子和函数定义的能力
- 无法在查询函数时存储任何更新的数据
首先确定窗口长度,它将控制最终输出中的随机性。我想你会希望这是一个小时或几个小时的订单
找出当前时间在哪个窗口内。在此窗口的开始和结束处计算引用函数。考虑由窗口的开始和结束时间给出的矩形以及由参考函数给出的最小值和最大值。将此矩形的角和常量种子输入PRNG。使用PRNG在矩形内选择一个随机点。该点将位于最终曲线上
对一个相邻窗口执行相同的计算。使用哪个相邻窗口取决于曲线上的第一个计算点位于当前时间的左侧还是右侧
既然曲线上有两个点(它们是可复制的和一致的),那么就必须迭代以下过程
最后一条曲线上有两点。考虑这些角落给出的矩形。将角落和你的恒定种子注入PRNG。使用该PRNG在矩形内选择一个随机点。该点将位于最终曲线上。丢弃一个不再需要的外部点
由于Y值被限制为整数,一旦曲线上的两个点具有相同的Y坐标,此过程最终将终止,并且您将知道,函数必须在这两个点之间保持恒定。您可以实现一个
其工作原理如下:首先将计数器设置为1。每次您想要增加计数(可以是某个循环的每次迭代或每次事件发生,但不需要随机确定),然后执行随机过程以确定它对计数器的影响
它可能没有效果,也可能有提高计数数量级的效果。概率取决于n个连续的公平硬币是否翻转了所有翻转的磁头,其中n是以二进制编码当前计数器值所需的位数。因此,一旦计数器变得相当高,就很难使其更高(计数器的状态模拟了一种现象,在这种情况下,您已经高估了计数,因此现在您需要大量的无事件来补偿,使计数更准确)
这是一种廉价的方法来存储一个非常大的集合的近似计数,但是没有理由不能将其用作随机递增计数器设备
如果您希望获得更高的精度,或者希望计数输出为更“正常”的数字,而不是总是2的幂,那么您可以创建几个Morris计数器,并在每一步将所有计数器上的当前计数集平均起来。作为快速解决方案,您可以使用类似的方法(java代码):
静态长f(最终整数x){
长r=0;//初始计数器
长n=36969L;//种子
对于(inti=0;i来说,对于下载之类的随机事件,一个很好的模型是泊松分布
||t |hit||
||0 |0 ||
||1 |3 ||
||2 |4 ||
||3 |6 ||
||4 |6 ||
||5 |8 ||
||6 |10 ||
||7 |13 ||
||8 |13 ||
||9 |16 ||
static long f(final int x) {
long r = 0; // initial counter
long n = 36969L; // seed
for (int i = 0; i <= x; i++) {
n = 69069L * n + 1234567L; // generate Ith random number
r += (n & 0xf); // add random number to counter
}
return r;
}
Counter = {
time:Date.now(),
count:0,
rate:0.45
};
Counter.seed = function(seed, startTime)
{
this.time = startTime,
this.count = 0,
this.prng = new Math.seedrandom(seed);
this.prng.getRandomInt = function(min, max) {
return Math.floor(this() * (max - min)) + min;
};
};
Counter.getNext = function(t){
var diff = t - this.time;
console.log(diff);
if(diff <= 0) return this.count;
this.time = t;
var max = Math.ceil(diff/100 * this.rate);
console.log("max: " + max);
this.count += this.prng.getRandomInt(0,max);
return this.count;
};
var results = [];
var today = Date.now();
Counter.seed("My Random Seed", today);
for (var i = 0; i < 7; i++) {
if(i === 4)
{
results.push(null);
} else {
var future = today + 86400000 * i;
results.push(Counter.getNext(future));
}
}
console.log(results);
var data = {
labels: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"],
datasets: [
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: results
}
]
};
var ctx = document.getElementById("myChart").getContext("2d");
var myLineChart = new Chart(ctx).Line(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.0/seedrandom.min.js">
</script>
<body>
<canvas id="myChart" width="600" height="400"></canvas>
</body>
</html>