zoukankan      html  css  js  c++  java
  • 亲自下载CSDN社区600万用户数据 设计两条编程题目考验你的.NET编程基础

    园子里这两天讨论的比较多的是CSDN-中文IT社区 600万用户数据在互联网上的传播,作为一名技术人员,暂且放下各自的想法的意见,仅仅从技术的角度来讲,分析和考验一下我们的编程基础。

    把下载到的压缩文件释放到硬盘中,得到文件www.csdn.net.sql。作为技术人员,对这个文件产生好奇心和编程的冲动。于是提出了下面的两条编程题目:

    1 如何把600万数据导入到SQL Server中?
    2 如何选择合适的密码加密方法?

    这个SQL文件有273MB,用SQL Server Management Studio打开它,会产生OutOfMemory异常,用记事本打开也很慢,推荐用Ultra Edit源代码编辑软件打开。

    估计大家的硬盘里面都有这个文件了,我也就不必给密码和邮件加上阴影了。

    用自己曾经注册到的邮件找一下,果然找到了自己的帐号和密码,确实是明文的。

    分析一下SQL文件,它是由换行符号分开的,以#分隔用户帐号,密码,电子邮件的格式。这和逗号分隔文件格式很相似,于是动手把它导入到SQL Server中。请参考下面的两行代码

    CREATE TABLE CsdnUser ([USER] NVARCHAR(MAX) )
      BULK INSERT CsdnUser FROM N'F:\www.csdn.net.sql'

    然后就是漫长的等待了,在4G内存,4核的Windows 7 x64的机器上,也跑了近5分钟才把数据从文本文件导入到SQL Server的CsdnUser表中。平时喜欢研究性能,性能改善研究,心中一阵窃喜。执行完成后,看到Messages中显示

    (6428632 row(s) affected),果然有600多万行数据,放数据库文件的磁盘一下子耗费了近6G的空间。

    跑一下SQL语句 SELECT [User] FROM CsdnUser,用户数据就已经存放到了SQL Server数据库文件中了。

    这样完成了文本文件到SQL Server的导入过程。如果我还想进一步的分解每一行的数据,像下面的结果显示这样

    SELECT  dbo.GetSplitOfIndex(User,'',1) AS [UserId]

                 dbo.GetSplitOfIndex(User,'',2) AS [Password]

                dbo.GetSplitOfIndex(User,'',3) AS [Email]

    FROM  CsdnUser

    则还需要写一个split函数,以分解开用#分开的用户数据。GetSplitOfIndex函数来源于互联网,地址是

    http://www.fengfly.com/plus/view-168590-1.html, 作者秩名,感谢他的智慧。函数的源代码如下所示

    CREATE FUNCTION [dbo].[GetSplitOfIndex]
    (
          @String NVARCHAR(MAX) ,  --要分割的字符串
          @split NVARCHAR(10) ,  --分隔符号
          @index INT --取第几个元素
    )
    RETURNS NVARCHAR(1024)
    AS 
        BEGIN
            DECLARE @location INT
            DECLARE @start INT
            DECLARE @next INT
            DECLARE @seed INT
     
            SET @String = LTRIM(RTRIM(@String))
            SET @start = 1
            SET @next = 1
            SET @seed = LEN(@split)
      
            SET @location = CHARINDEX(@split, @String)
            WHILE @location <> 0
                AND @index > @next 
                BEGIN
                    SET @start = @location + @seed
                    SET @location = CHARINDEX(@split, @String, @start)
                    SET @next = @next + 1
                END
            IF @location = 0 
                SELECT  @location = LEN(@String) + 1 
      
            RETURN SUBSTRING(@String,@start,@location-@start)
        END

    自SQL Server 2005起就开始集成CLR,允许.NET托管代码运行于SQL Server中,用我们熟悉的.NET API可以轻易的完成任务。打开Visual Stdio 2010,创建一个SQL Server CLR项目,SQL Server CLP函数的源代码清单如下

    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlString Split(string UserLine,int Index)
    {
            if (!string.IsNullOrEmpty(UserLine))
            {
                string[] lines = Regex.Split(UserLine, " # ");
                if (lines.Length == 3)
                    return new SqlString(lines[Index]);
                else
                    throw new ApplicationException("invalid input line");
            }
            return new SqlString("");
    }

    它的调用方法和TSQL函数的方式一样,如下图所示

    SELECT  dbo.Split(User,0) AS  [User Id]

                  dbo.Split(User,1)  AS [Password]

                  dbo.Split(User,2) AS [Email]

          FROM CsdnUser

    顺利完成第一题,如果你有更好的方法,欢迎留言。

    对于密码是否用明文,是否要加密,各种情况下所采取的方法都有道理。不给密码加密,明文传送是不值得推荐,不过冒似很多系统都是用明文保存在数据库中的。如果你担心明文不好,容易被人家获取到,可以采用可逆的加密。请参考我的文章《数据加密小工具》,它对需要保护的数据进行简单的加密,也很容易的逆反到当初的明文

    image

    在我的知识管理系统Data Solution的用户反馈功能中,用户输入反馈的内容,发送到指定的邮箱中,因为使用的是smtp的方式,所以要把用户名和密码写到程序中去,但为了防止别人很轻易的从IL代码中读到到我的邮件的帐号和密码,我就使用了上面的可逆加密的方法,把邮件帐号和密码进行加密后,再放到程序代码中,这样可以增加被破解的难度。也没有把很重要的资料放到这个用于接受用户反馈的邮件帐号中,毕竟还是可能被人家破解的。

    再进一步的,可以采用.NET提供的算法,进行Hash运算或是加密。MD5是公认的不可逆的加密算法,它的调用方法如下

    byte[] Original = Encoding.Default.GetBytes(txt_Source.Text); 
    MD5 s1 = MD5.Create(); //使用MD5 
    byte[] Change = s1.ComputeHash(Original);  加密 
    txt_Result.Text = Convert.ToBase64String(Change);

    请参考文章《使用MD5將字串加密 C# VS2005 Sample Code》学习MD5的调用方法。

    如果你需要MD5的调用例子代码,下面的代码应该可以帮助到你,代码来原于园子里的朋友,
    地址是http://www.cnblogs.com/konooo/archive/2009/01/22/1379920.html 

     /// MD5 16位加密 加密后密码为大写
     /// </summary>
    /// <param name="ConvertString"></param>
    /// <returns></returns>
    public static string GetMd5Str(string ConvertString)
    {
          MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
          string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
          t2 = t2.Replace("-", "");
          return t2;
    } 
    /// <summary>
    /// MD5 16位加密 加密后密码为小写
    /// </summary>
    /// <param name="ConvertString"></param>
    /// <returns></returns>
    public static string GetMd5Str(string ConvertString)
    {
          MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
          string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
          t2 = t2.Replace("-", "");
          t2 = t2.ToLower();
          return t2;
    }
    
    /// <summary>
    /// MD5 32位加密
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    static  string UserMd5(string str)
    {
          string cl = str;
          string pwd = "";
          MD5 md5 = MD5.Create();//实例化一个md5对像
          // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 
          byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
          // 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
          for (int i = 0; i < s.Length; i++)
          {
           // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符 
           pwd = pwd + s[i].ToString("X");
          }
          return pwd;
    }

    前几年是经常在CSDN上逛,也喜欢它的下载频道,可以找到很多资源,后来下载资源要积分的,没有分就不能下载,于是自己注册了多个CSDN的帐号,只用来下载资源。这里我有两句微词,既然是共享目的,为何要限制别人下载呢?新浪的爱问知识人就没有这么复杂的下载规则,即使被下载的文件需要积分,你也可以找到不要分的,免限制下载的资源。还有一条规则,如果你的CSDN帐号不够一定的级别,只能上传,但不能删除你上传的文件。我自己也曾在CSDN上发布过软件程序,后来有新版本发布,无法自己删除旧版本的程序,要到论坛去发贴子,依靠管理员才能删除,就这一条,使我彻底放弃了把CSDN作为程序代码的发布渠道。 不过,CSDN还是对我们的技术有过很大的帮助,遇到问题用Baidu搜索到的头条通常就是CSDN的论坛的贴子,这一点要对CSDN表示感谢和致敬。

  • 相关阅读:
    用算法合并数组
    Redis各个数据类型的使用场景
    seesion工作原理
    自删除道指令程序
    uva 1335
    《生活在Linux中》之:使用Bash就是使用Emacs
    手动配置S2SH三大框架报错(三)
    数据和C
    IOS之【地图MapKit】
    我工作这几年(五)-- Android学习4.5月总结(一)
  • 原文地址:https://www.cnblogs.com/JamesLi2015/p/2298825.html
Copyright © 2011-2022 走看看