没有合适的资源?快使用搜索试试~ 我知道了~
首页简单高效的短链接生成服务C#实现
简单高效的短链接生成服务C#实现
11 下载量 46 浏览量
更新于2023-03-16
评论 1
收藏 102KB PDF 举报
项目中有一处需求,需要把长网址缩为短网址,把结果通过短信、微信等渠道推送给客户。刚开始直接使用网上现成的开放服务,然后在某个突然手痒想自己动手实现一个别具特色的长网址(文本)缩短服务。 由于以前做过socket服务,对数据包的封装排列还有些印象,因此,短网址服务我第一反应是先设计数据的存储格式,我这里没有采用数据库,而是使用2个文件来实现: Url.db存储用户提交的长网址文本,Url.idx 存储数据索引,记录每次提交数据的位置(Begin)与长度(Length),还有一些附带信息(Hits,DateTime)。由于每次添加长网址,对两个文件都是进行Append操作,因此
资源详情
资源评论
资源推荐
简单高效的短链接生成服务简单高效的短链接生成服务C#实现实现
项目中有一处需求,需要把长网址缩为短网址,把结果通过短信、微信等渠道推送给客户。刚开始直接使用网上现成的开放服务,然后在某个突然手痒想自己动手实现一个别具特色的长网址(文
本)缩短服务。
由于以前做过socket服务,对数据包的封装排列还有些印象,因此,短网址服务我第一反应是先设计数据的存储格式,我这里没有采用数据库,而是使用2个文件来实现:
Url.db存储用户提交的长网址文本,Url.idx 存储数据索引,记录每次提交数据的位置(Begin)与长度(Length),还有一些附带信息(Hits,DateTime)。由于每次添加长网址,对两个文件都是进
行Append操作,因此即使这两个文件体积很大(比如若干GB),也没有太大的IO压力。
再看看Url.idx文件的结构,ID是主键,设为Int64类型,转换为字节数组后的长度为8,紧跟的是Begin,该值是把长网址数据续写到Url.db文件之前,Url.db文件的长度,同样设为Int64类型。长网址
的字符串长度有限,Int16足够使用了,Int16.MaxValue==65536,比Url规范定义的4Kb长度还大,Int16转换为字节数组后长度为2字节。Hits表示短网址的解析次数,设为Int32,字节长度为
4,DateTime 设为Int64,长度8。由于ID不会像数据库那样自动递增,因此需要手工实现。因此在开始写入Url.idx前,需要预先读取后一行(行是虚的,其实是后30字节)中的的ID值,递增后才开始写
入新的一行。
也是说每次提交一个长网址,不管数据有多长(大不能超过65536字节),Url.idx 文件都固定增加 30 字节。
数据结构一旦明确下来,整个网址缩短服务变得简单明了。例如连续两次提交长网址,可能得到的短网址为http://域名/1000,与http://域名/1001,结果显然很丑陋,域名后面的ID全是数字,而且递
增关系明显,很容易暴力枚举全部的数据。而且10进制的数字容量有限,一次提交100万条的长网址,产生的短网址越来越长,失去意义。
因此下面开始对ID进行改造,改造的目标有2:
1、增加混淆机制,相邻两个ID表面上看不出区别。
2、增加容量,一次性提交100万条长网址,ID的长度不能有明显变化。
简单直接的混淆机制,是把10进制转换为62进制(0-9a-zA-Z),由于顺序的abcdef…也很容易猜到下一个ID,因此62进制字符序列随机排列一次:
/// <summary>
/// 生成随机的0-9a-zA-Z字符串
/// </summary>
/// <returns></returns>
public static string GenerateKeys()
{
string[] Chars =
"0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z".Split(',');
int SeekSeek = unchecked((int)DateTime.Now.Ticks);
Random SeekRand = new Random(SeekSeek);
for (int i = 0; i < 100000; i++)
{
int r = SeekRand.Next(1, Chars.Length);
string f = Chars[0];
Chars[0] = Chars[r – 1];
Chars[r – 1] = f;
}
return string.Join("", Chars);
}
运行一次上面的方法,得到随机序列:
string Seq = "s9LFkgy5RovixI1aOf8UhdY3r4DMplQZJXPqebE0WSjBn7wVzmN2Gc6THCAKut";
用这个序列字符串替代0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,具有很强的混淆特性。一个10进制的数字按上面的序列转换为62进制,将变得面目全非,
附转换方法:
/// <summary>
/// 10进制转换为62进制
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
private static string Convert(long id)
{
if (id < 62)
{
return Seq[(int)id].ToString();
}
int y = (int)(id % 62);
long x = (long)(id / 62);
return Convert(x) + Seq[y];
}
/// <summary>
/// 将62进制转为10进制
/// </summary>
/// <param name="Num"></param>
/// <returns></returns>
private static long Convert(string Num)
{
long v = 0;
int Len = Num.Length;
for (int i = Len – 1; i >= 0; i–)
{
int t = Seq.IndexOf(Num[i]);
double s = (Len – i) – 1;
long m = (long)(Math.Pow(62, s) * t);
v += m;
}
return v;
}
例如执行 Convert(123456789) 得到 RYswX,执行 Convert(123456790) 得到 RYswP。
如果通过分析大量的连续数值,还是可以暴力算出上面的Seq序列值,进而猜测到某个ID左右两边的数值。下面进一步强化混淆,ID每次递增的单位不是固定的1,而是一个随机值,比如
1000,1005,1013,1014,1020,毫无规律可言。
private static Int16 GetRnd(Random seekRand)
{
Int16 s = (Int16)seekRand.Next(1, 11);
return s;
}
即使把62进制的值逆向计算出10进制的ID值,也难于猜测到左右两边的值,大大增加暴力枚举的难度。难度虽然增加,但是连续产生的2个62进制值如前面的RyswX与RyswP,仅个位数不同,还是
很像,因此我们再进行第三次简单的混淆,把62进制字符向左(右)旋转一定次数(解析时反向旋转同样的次数):
/// <summary>
/// 混淆id为字符串
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
private static string Mixup(long id)
{
string Key = Convert(id);
int s = 0;
foreach (char c in Key)
{
s += (int)c;
}
int Len = Key.Length;
int x = (s % Len);
weixin_38600253
- 粉丝: 6
- 资源: 905
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- zigbee-cluster-library-specification
- JSBSim Reference Manual
- c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf
- 建筑供配电系统相关课件.pptx
- 企业管理规章制度及管理模式.doc
- vb打开摄像头.doc
- 云计算-可信计算中认证协议改进方案.pdf
- [详细完整版]单片机编程4.ppt
- c语言常用算法.pdf
- c++经典程序代码大全.pdf
- 单片机数字时钟资料.doc
- 11项目管理前沿1.0.pptx
- 基于ssm的“魅力”繁峙宣传网站的设计与实现论文.doc
- 智慧交通综合解决方案.pptx
- 建筑防潮设计-PowerPointPresentati.pptx
- SPC统计过程控制程序.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0