用ILSpy查看Session.SessionID的生成算法

  

缘由

  asp.net Session在InProc模式下,容易丢失,经常需要重新登录,且不支持分布式共享。  

所以在研究Redis实现原生的Session,本来想用GUID作为key存入cookie,又在想能不能实现跟Session一样的id

实现

  ILSpy 是一个开源的.NET反编译工具,简洁强大易用是它的特征。在绝大多数情况下,它都能很好的完成你对未知程序集内部代码的探索。

ILSpy 下载地址:点击下载

  在VS中可以得知SessionID是System.Web.SessionState命名空间的HttpSessionState类下的属性。

在ILSpy中搜索HttpSessionState,找到Session属性,是IHttpSessionState接口对象创建的。

  查看HttpSessionState的构造函数,原来IHttpSessionState是从构造函数传过来的。

  本来是想通过搜索构造函数找到是哪传过来这个对象的,只是ILSpy只提供类型,成员,常量的搜索

折腾了好久,终于找到IHttpSessionState的接口实现类HttpSessionStateContainer

  DelayedGetSessionId方法

  CreateSessionId方法

  在追踪CreateSessionID方法,是个接口中定义的方法

  搜索CreateSessionID方法,找到具体的现实

  最后找到Create方法的所在类

测试

  具体的代码:

internal static class SessionId
    {
        internal const int NUM_CHARS_IN_ENCODING = 32;
        internal const int ENCODING_BITS_PER_CHAR = 5;
        internal const int ID_LENGTH_BITS = 120;
        internal const int ID_LENGTH_BYTES = 15;
        internal const int ID_LENGTH_CHARS = 24;
        private static char[] s_encoding;
        private static bool[] s_legalchars;
        internal static bool IsLegit(string s)
        {
            if (s == null || s.Length != 24)
            {
                return false;
            }
            bool result;
            try
            {
                int num = 24;
                while (--num >= 0)
                {
                    char c = s[num];
                    if (!SessionId.s_legalchars[(int)c])
                    {
                        result = false;
                        return result;
                    }
                }
                result = true;
            }
            catch (IndexOutOfRangeException)
            {
                result = false;
            }
            return result;
        }
        internal static string Create(ref RandomNumberGenerator randgen)
        {
            if (randgen == null)
            {
                randgen = new RNGCryptoServiceProvider();
            }
            byte[] array = new byte[15];
            randgen.GetBytes(array);
            return SessionId.Encode(array);
        }
        static SessionId()
        {
            SessionId.s_encoding = new char[]
            {
                ‘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‘,
                ‘0‘,
                ‘1‘,
                ‘2‘,
                ‘3‘,
                ‘4‘,
                ‘5‘
            };
            SessionId.s_legalchars = new bool[128];
            for (int i = SessionId.s_encoding.Length - 1; i >= 0; i--)
            {
                char c = SessionId.s_encoding[i];
                SessionId.s_legalchars[(int)c] = true;
            }
        }
        private static string Encode(byte[] buffer)
        {
            char[] array = new char[24];
            int num = 0;
            for (int i = 0; i < 15; i += 5)
            {
                int num2 = (int)buffer[i] | (int)buffer[i + 1] << 8 | (int)buffer[i + 2] << 16 | (int)buffer[i + 3] << 24;
                int num3 = num2 & 31;
                array[num++] = SessionId.s_encoding[num3];
                num3 = (num2 >> 5 & 31);
                array[num++] = SessionId.s_encoding[num3];
                num3 = (num2 >> 10 & 31);
                array[num++] = SessionId.s_encoding[num3];
                num3 = (num2 >> 15 & 31);
                array[num++] = SessionId.s_encoding[num3];
                num3 = (num2 >> 20 & 31);
                array[num++] = SessionId.s_encoding[num3];
                num3 = (num2 >> 25 & 31);
                array[num++] = SessionId.s_encoding[num3];
                num2 = ((num2 >> 30 & 3) | (int)buffer[i + 4] << 2);
                num3 = (num2 & 31);
                array[num++] = SessionId.s_encoding[num3];
                num3 = (num2 >> 5 & 31);
                array[num++] = SessionId.s_encoding[num3];
            }
            return new string(array);
        }
    }

  调用:

 public partial class Contact : Page
    {

        protected void Page_Load(object sender, EventArgs e)
        {
            string SessionId = CreateSessionID(Context);
            Response.Write(SessionId+"<br/>");       Response.Write(Session.SessionID);
            Response.End();
        }

        private RandomNumberGenerator _randgen;
        public virtual string CreateSessionID(HttpContext context)
        {

            return SessionId.Create(ref this._randgen);
        }

    }

效果截图:

时间: 2024-10-26 07:12:28

用ILSpy查看Session.SessionID的生成算法的相关文章

cookie,session,sessionid

http协议是无状态的,意思是每次请求的状态不会保存.因此,产生了cookie,session之类保存会话状态的机制.1.什么是cookiecookie将信息存储在客户端浏览器中.cookie的内容主要包括:key,value,expire_time,path(路径),domain(域)浏览器发送请求是会查找对应的path,domain,把符合的cookie自动发送给服务器. 2.什么是sessionsession在服务器端生成,然后会将对应的sessionid在浏览器端使用cookie保存起来

解析PHP默认的session_id生成算法

作为一个web程序猿,我们对session肯定都不陌生,session id是我们各自在服务器上的一个唯一标志,这个id串既可以由php自动来生成,也可以由我们来赋予.你们可能和我一样,很关心php自动生成的那个id串是怎么来的,冲突的概率有多大,以及容不容易被别人计算出来,所以有了下文. 我们下载一份php5.3.6的源码,进入/ext/session目录,生成session id的函数位于session.c文件的345行,下面详细介绍一下这个函数.为了方面理解,我调整了一些代码的顺序. PH

Wish App逆向分析app_device_id字段生成算法

概述 本文对Wish App进行了反编译,对应用中app_device_id字段的生成算法进行了逆向分析. 使用到的工具有: 1. Apktool:获取资源文件和smali 反汇编代码 2. dex2jar:反编译apk,将其中的classes.dex转化成jar文件 3. jd-gui:打开jar文件,查看java源码 反编译环境:mac osx apk反编译获得java代码和smali反汇编代码 1. 从google play下载Wish.apk 2. 使用dex2jar把apk解包,将其中

基于上下文无关文法的句子生成算法

前言 算法来自国外大牛的一篇博客:点击此处可查看 算法不涉及任何人工智能领域知识,仅仅是针对上下文无关文法提出的生成句子的思路. 上下文无关文法 上下文无关文法仅与句子结构有关,与上下文语意无关. 属性|单词 --|-- S |NP VP NP |Det N / Det N NP |I / he / she / Joe VP |V NP / VP Det |a / the / my / his N |elephant / cat / jeans / suit V |kicked / follow

等高线生成算法(转载)

等高线生成算法 输入:离散的采样点坐标和高度值(x_0,y_0,value_0),(x_1,y_1,value_1)......(x_n, y_n, value_n) 输出:等高线图,如下所示 wiki上的Marching squares算法对此有很好的说明,我也是按照wiki上面的步骤来实现这个算法的,下面对该算法的步骤进行简要说明. 输入参数: 1.点的集合(x_0,y_0,value_0),(x_1,y_1,value_1)......(x_n, y_n, value_n) ; 2.高度值

清华版CG 实验2 直线生成算法实现

1.实验目的: 理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法. 2.实验内容: (1) 根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果: (2) 指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告: (3) 根据示范代码,将其改造为圆的光栅化算法,写入实验报告: (4) 了解和使用OpenGL的生成直线的命令,来验证程序运行结果. 3.实验原理: 示范代码原理参见教材直线

微信红包生成算法 (解)

/** * 微信红包生成算法 * * @param int $total 红包金额 * @param int $num 拆分数量 * @param int $min 拆分的红包最小金额数目 */function set_packet($total, $num, $min = 0.01){ for ($i = 1; $i < $num; $i++) { //随机安全上限 $safe_total = ($total-($num-$i)*$min)/($num-$i); //红包金额 $money =

[迷宫中的算法实践]迷宫生成算法&mdash;&mdash;Prim算法

       普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小.该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现:并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现:1959年,艾兹格·迪科斯彻再次发现了该算法.因此,在某些场合,普里姆

计算机图形学(二)输出图元_6_OpenGL曲线函数_1_圆生成算法

OpenGL曲线函数 生成圆和椭圆等基本曲线的函数并未作为图元功能包含在OpenGL核心库中.但该库包含了显示Bezier样条的功能,该曲线是由一组离散点定义的多项式.OpenGL实用库(GLU)中包含有球面和柱面等三维曲面函数以及生成B样条的函数,它是包含简化Bezier曲线的样条曲线的总集.我们可以使用有理B样条显示圆.椭圆和其他二维曲线.此外,OpenGL实用工具包(GLUT)中还有可以用来显示某些三维曲面(如球面.锥面和其他形体)的函数.然而,所有这些函数比本章中介绍的基本图元应用得更多