Wind-Eagle

No pain,no gain!
posts - 66, comments - 60, trackbacks - 0, articles - 4
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

2010年4月12日

using System;
using System.Collections.Generic;
using System.Globalization;

namespace Encoding
{
    
internal class Program
    {
        
private static void Main(string[] args)
        {
            var gb1 
= System.Text.Encoding.GetEncoding("Unicode");
            Console.WriteLine(gb1.GetString(gb1.GetBytes(
"测试")));

            var gb0 
= System.Text.Encoding.GetEncoding("UTF-8");
            Console.WriteLine(gb0.GetString(gb0.GetBytes(
"测试")));

            var gb 
= System.Text.Encoding.GetEncoding("GB2312");
            Console.WriteLine(gb.GetString(gb.GetBytes(
"测试")));

            
#region 测试代码

            Console.WriteLine(IsChineseLetter(
"测试"0));
            Console.WriteLine(ChineseLetterCode(
"测试"0));
            Console.WriteLine(ChineseLetterFromCode(ChineseLetterCode(
"测试"0)));

            Console.WriteLine(gb1.GetString(
                Utf8_2_Unicode(gb0.GetBytes(
"测试test"))));

            
//http://qkzz.net/article/3d697483-a5ae-4b50-9ae9-45dc6dd26141.htm
            
//http://topic.csdn.net/u/20090617/18/1907627e-ce38-4ae5-9755-1cc349a4ed1a.html
            
//一级汉字有 3755 个, 40 * 94=3760 个, 其中 d7fe, d7fd, d7fc, d7fb, d7fa 五位置为空
            for (byte i = 0xb0; i < 0xd8; i++)
            {
                
for (byte j = 0xa1; j < (i != 0xd7 ? 0xff : 0xfa); j++)
                {
                    Console.Write(gb.GetString(
new[] {i, j}));
                    
if (j == 0xc7 || j == 0xee || j == (i != 0xd7 ? 0xfe : 0xf9))
                        Console.WriteLine();
                }
            }

            Console.WriteLine(GetChineseLetterFromGb2312(
0));
            Console.WriteLine(GetChineseLetterFromGb2312(
3754));

            
//汉字的 Unicode 编码范围
            for (var i = 19968; i <= 40959; i++)
            {
                Console.Write(ChineseLetterFromCode(i));
            }

            
#endregion

            Console.Read();
        }

        
public static string GetChineseLetterFromGb2312(int rNum)
        {
            
if (rNum < 0 || rNum > 3754)
                
throw new ArgumentOutOfRangeException("rNum""超出一级汉字的范围!");
            var gb 
= System.Text.Encoding.GetEncoding("GB2312");
            
return gb.GetString(new[] {(byte) (0xb0 + (rNum/94)), (byte) (0xa1 + (rNum%94))});
        }

        
/// <summary>
        
/// UTF8 汉字字节流转成 Unicode 汉字字节流
        
/// </summary>
        
/// <param name="input"></param>
        
/// <see cref="http://hi.baidu.com/hyqsoft/blog/item/263795a164d1728346106464.html"/>
        public static byte[] Utf8_2_Unicode(byte[] input)
        {
            var ret 
= new List<byte>();
            
for (var i = 0; i < input.Length; i++)
            {
                
if (input[i] >= 240// 11110xxx
                {
                    
//i += 3;
                    throw new Exception("四字节的 UTF-8 字符不能转换成两字节的 Unicode 字符!");
                }
                
//else if (input[i] >= 224)
                if (input[i] >= 224// 1110xxxx
                {
                    ret.Add((
byte) ((input[i + 2& 63| ((input[i + 1& 3<< 6)));
                    ret.Add((
byte) ((input[i] << 4| ((input[i + 1& 60>> 2)));
                    i 
+= 2;
                }
                
else if (input[i] >= 192// 110xxxxx
                {
                    ret.Add((
byte) ((input[i + 1& 63| ((input[i] & 3<< 6)));
                    ret.Add((
byte) ((input[i] & 28>> 2));
                    i 
+= 1;
                }
                
else
                {
                    ret.Add(input[i]);
                    ret.Add(
0);
                }
            }
            
return ret.ToArray();
        }

        
#region 汉字与Unicode编码

        
public static bool IsChineseLetter(string input, int index)
        {
            var chfrom 
= Convert.ToInt32("4e00"16); //范围(0x4e00~0x9fff)转换成int(chfrom~chend)
            var chend = Convert.ToInt32("9fa5"16);
            
if (input != "")
            {
                
//var code = Char.ConvertToUtf32(input, index);
                var gb = System.Text.Encoding.GetEncoding("Unicode");
                var b 
= gb.GetBytes(input.Substring(index, 1));
                var code 
= b[0+ b[1]*0x100;

                
return code >= chfrom && code <= chend;
            }
            
return false;
        }

        
public static int ChineseLetterCode(string input, int index)
        {
            var chfrom 
= Convert.ToInt32("4e00"16); //范围(0x4e00~0x9fff)转换成int(chfrom~chend)
            var chend = Convert.ToInt32("9fa5"16);
            
if (input != "")
            {
                var code 
= Char.ConvertToUtf32(input, index);

                
return code >= chfrom && code <= chend ? code : 0;
            }
            
return 0;
        }

        
public static string ChineseLetterHexCode(string input, int index)
        {
            var code 
= ChineseLetterCode(input, index);
            
return code != 0 ? code.ToString("X4") : string.Empty;
        }

        
public static string ChineseLetterFromCode(int code)
        {
            var chfrom 
= Convert.ToInt32("4e00"16); //范围(0x4e00~0x9fff)转换成int(chfrom~chend)
            var chend = Convert.ToInt32("9fa5"16);
            
//return code >= chfrom && code <= chend ? Char.ConvertFromUtf32(code) : string.Empty;
            if (code >= chfrom && code <= chend)
            {
                var gb 
= System.Text.Encoding.GetEncoding("Unicode");
                var b 
= new[] {(byte) (code%0x100), (byte) (code/0x100)};
                
return gb.GetString(b);
            }
            
return string.Empty;
        }

        
public static string ChineseLetterFromHexCode(string hexCode)
        {
            
//var code = Convert.ToInt32(hexCode, 16);
            var code = int.Parse(hexCode, NumberStyles.HexNumber);
            
return ChineseLetterFromCode(code);
        }

        
#endregion
    }
}


包含了处理汉字与Unicode编码转换的多种方法,从UTF-8字节流得到Unicode字节流的方法(从而可以用 Unicode编码处理方法处理UTF-8编码)。研究GB2312编码规范,得到最简单的根据一个整数得到一个一级汉字的方法,根据这个方法可以写出最简单生成一级汉字验证码程序~

posted @ 2010-04-12 11:30 Andrew Yin 阅读(495) 评论(1) 编辑

2008年12月23日

今天看了看C++中模板的概念,按照教程写了一个简单的链表模板:

//*********************
//** listtmp.h **
//*********************
#ifndef LIST
#define LIST

#include 
<iostream>

template
<class T> class List{
public:
    List();
    
void Add(T&);
    
void Remove(T&);
    T
* Find(T&);
    T
* Current();
    
void Restart();
    
void Next();
    
void PrintList();
    
~List();
protected:
    
struct Node{
        Node
* pNext;
        T
* pT;
    };
    Node 
*pFirst;  //链首结点指针
    Node *pCurpos; //当前节点
};

template
<class T> List<T>::List()
{
    pFirst 
= 0;
    pCurpos 
= 0;
}

template
<class T> T* List<T>::Current()
{
    
if(pCurpos)
        
return pCurpos->pT;
    
return 0;
}

template
<class T> void List<T>::Restart()
{
    
if(pFirst)
        pCurpos 
= pFirst;
    
else
        pCurpos 
= 0;
}

template
<class T> void List<T>::Next()
{
    
if(pCurpos)
        pCurpos 
= pCurpos->pNext;
}

template
<class T> void List<T>::Add(T& t)
{
    Node
* temp = new Node;
    temp
->pT =&t;
    temp
->pNext = pFirst;
    pFirst 
= temp;
}

template
<class T> void List<T>::Remove(T& t)
{
    Node 
*= 0//待删结点
    if(*(pFirst->pT)==t) //T类中==须有定义
    {
        q 
= pFirst;
        pFirst 
= pFirst->pNext; //待删结点在链首时的脱链
    }
    
else
    {
        
for(Node* p=pFirst; p->pNext; p=p->pNext)
        { 
//顺链查找
            if(*(p->pNext->pT)==t)
            {
                q 
= p->pNext;
                p
->pNext = q->pNext;
                
break;
            }
        }
    }
    
if(q)
    {
        delete q
->pT;
        delete q;
    }
}

template
<class T> T* List<T>::Find(T& t)
{
    
for(Node* p=pFirst; p; p=p->pNext)
        
if(*(p->pT)==t)
            
return p->pT;

    
return 0;
}

template
<class T> void List<T>::PrintList()
{
    
for(Node* p=pFirst; p; p=p->pNext)
        cout 
<<*(p->pT)<<" "//须有T的友元处理T对象输出

    cout 
<<endl;
}

template
<class T> List<T>::~List()
{
    Node
* p;
    
while(p = pFirst){
        pFirst 
= pFirst->pNext;
        delete p
->pT;
        delete p;
    }
    pFirst 
= 0;
}

#endif


并且创建了一个josephus问题的解决方案:

//******************************
//**    Josephus问题解法六    **
//**    jose6.cpp             **
//******************************

#include 
<iostream>
#include 
"listtmp.h"
#include 
<iomanip>
using namespace std;

void Display(int);
void Step(int m);
void Init(int);

List
<int> josephus;                  //创建单向链表模板类的全局对象

void main()
{
  
int n=9999, s=274, m=291;                 //随取三个合理的整数
  
//int* ap=
  Init(n);
  Step(s);
  
for(int i=1; i<n; i++){
    Step(m);
    
int* tmp = josephus.Current();
    Display(
*tmp);
    Step(
1);//josephus.Next();
    josephus.Remove(*tmp);
  }
  cout 
<<"\nThe winner is "<<*josephus.Current() << endl;
  
//delete[]ap;
}

//以下是构造链表,初始化结点编号的函数
void Init(int n)
{
  
//int* a = new int[n];
  for(int i=0; i<n; i++)
  {
    
//a[i] = n - i;
    Display(i+1);
    josephus.Add(
*new int(n - i));
  }
  Display ( 
-1 );
  josephus.Restart();           
//初始化迭代算子
  
//return a;
}

//以下是显示一个结点编号的函数
void Display(int n)
{
  
static int k;
  
if(n<0){
    k 
= 0;
    cout 
<<endl;
    
return;
  }
  cout 
<<setw(5<<n;
  
if (!(++k%10))
    cout 
<<endl;
}

//以下是要将指针从当前位置挪到往下数第m个结点的位置
void Step(int m)
{
  
for(int i=0; i<m; i++){
    josephus.Next();
    
if(!josephus.Current())    //模拟环链表操作
      josephus.Restart();
  }
}

 

深入学习C++基础知识。。。。

posted @ 2008-12-23 15:16 Andrew Yin 阅读(388) 评论(0) 编辑

2008年12月16日

一、无参函数:

 

irb(main):010:0> def h
irb(main):
011:1> puts "Hello World!"
irb(main):
012:1> end
=> nil

irb(main):
013:0> h
Hello World!
=> nil
irb(main):
014:0> h()
Hello World!
=> nil

在 Ruby 里调用函数就像提起 Ruby 的名字一样简单。如果函数不需要接受参数,您只要提到它就够了。您可以加一对括号,但不是必需的。

二、有参函数

irb(main):015:0> def h(name)
irb(main):
016:1> puts "Hello #{name}!"
irb(main):
017:1> end
=> nil
irb(main):0
18:0> h("Matz")
Hello Matz!
=> nil

通过#{parameterName}来引用参数。等等,似乎参数没有参数类型哦。是的,这就是鼎鼎大名的“鸭子型”的体现。

三、默认参数

irb(main):019:0> def h(name = "World")
irb(main):
020:1> puts "Hello #{name.capitalize}!"
irb(main):
021:1> end
=> nil
irb(main):
022:0> "chris"
Hello Chris!
=> nil
irb(main):
023:0> h
Hello World!
=> nil

 

参数可以用括号来指定,也可以直接指定。

当有参数有默认值的时候,可以不指定参数,就像无参函数一样调用。

问题:

参数的返回值问题。

多参数的函数的调用问题。

多参数的函数中,默认参数的位置是否必须位于最后?

好了,下一篇讲Ruby中的类。

posted @ 2008-12-16 12:13 Andrew Yin 阅读(71) 评论(0) 编辑

关于Ruby的介绍请参照:http://www.ruby-lang.org/zh_CN/about/

一、IRB

     交互式Ruby帮助和控制台程序,Windows下成为fxri。

     在IRB中可以直接执行Ruby代码。如:

irb(main):001:0> "Hello World"
=> "Hello World"

二、puts命令和nil

irb(main):002:0> puts "Hello World"
Hello World
=> nil

puts 是 Ruby 语言里用来打印的基本命令。那 => nil 是什么?其实是命令的返回值。 puts 命令永远返回 nil,nil 也是 Ruby 的空值。

三、表达式执行

前面的"Hello World"就是一个表达式,其结果就是其本身,而puts "Hello World"则可以看作是一个命令语句,其可以没有返回值(也就是返回nil).

其他的表达式执行的例子:

irb(main):003:0> 3+2
=> 5

irb(main):
004:0> 3*2
=> 6

irb(main):
005:0> 3**2
=> 9

irb(main):
006:0> Math.sqrt(9)
=> 3.0

irb(main):
007:0> a = 3 ** 2
=> 9
irb(main):00
8:0> b = 4 ** 2
=> 16
irb(main):00
9:0> Math.sqrt(a+b)
=> 5.0

 

**表示次方,Math.sqrt表示开平方。

四、模块的概念

即代码分组。

Math 是一个自带的数学模块。模块在 Ruby 里有两个作用。第一:把功能相似的函数放到同一个名称下。Math 模块还有 sin()tan() 这样的函数。

接下来的是一个点。点是干什么用的?点是用来告诉一个接收者它所要接受的信息。什么是信息?在这个例子里面,信息就是 sqrt(9),意思就是调用 sqrt 函数,并给它 9 作为参数。当然 sqrt 就是 “square root” 的缩写。

这个函数的返回值是 3.0。您一定发现了它不光只是3,还多了小数部分。这是因为大多数情况下,开方的结果并不是整数,所以 sqrt 始终会返回浮点数

五、变量

如果我们想记住运算结果呢?存到变量里吧。

irb(main):007:0> a = 3 ** 2
=> 9
irb(main):00
8:0> b = 4 ** 2
=> 16
irb(main):00
9:0> Math.sqrt(a+b)
=> 5.0
好了,第一篇就写到这里吧,我是边看官方文档边做的笔记,如果我的理解有错误,欢迎指正!

posted @ 2008-12-16 11:22 Andrew Yin 阅读(108) 评论(0) 编辑

2008年12月10日

这段时间又在研究AOP了,对各种动态注入原理的AOP已经不感兴趣了,想研究一下静态注入的AOP,首当其冲的是PostSharp。

PS:Routing 和ASP.NET MVC的文章暂时放一放了

所谓静态注入,指的是在编译好的程序集(最好叫装配集)中的类型或者某个方法里注入IL代码(而不是在程序集的运行时注入),注入的地方称为"Join-Point".

有好多工具都可以读写程序集,注入IL代码,如Reflector的一个插件。但是PostSharp是在你编译一个程序集的时候就把IL注入到程序集里去了。

PostSharp并不像ReSharp一样,它不是VS的一个插件,它也不是在编辑器里修改代码的。

那么,PostSharp是如何起作用的呢?

它是怎么把自己插入到编译器的编译生成过程的呢?

我们都知道VS是通过MSBiuld来执行生成过程的,所以其实PostSharp是把自己作为一系列的Build Task来插入到生成过程的。

然后它修改了VS调用MSBiuld的默认配置。从而使VS的Build命令执行了它所指定的Task。下面的图说明了PostSharp的原理:

但是要真正理解静态注入的原理,要理解IL读写,还需要深入了解.net程序集,了解CLI和IL。

要真正知道PostSharp是如何工作的就必须了解MSBuild,知道怎么执行自定义的Build Task.

有很多东西VS都给我们做了,所以我们不了解,有很多开发人员现在还认为.NET 的程序集就是一个托管DLL文件呢!

接下来我将要写一些关于这方面的文章。

不过大家可以在下面的两个链接找到MSBuild的文档:

http://msdn.microsoft.com/zh-cn/library/wea2sca5.aspx

http://msdn.microsoft.com/zh-cn/library/0k6kkbsd.aspx

引用一下PostSharp文档里的一段:

 

Difference between the PostSharp Code Object Model and System.Reflection

PostSharp uses the entities defined in the specifications of the Common Language Infrastructure (CLI). However, developers are more familiar with the concepts of System.Reflection. They should be aware than System.Reflection includes great simplifications with respect to CLI specifications. CLI is module oriented. A module is an atomic artifact that can bind to other modules to form complete applications. In order to refer to types defined outside the current module, one uses references. By contrast, System.Reflection lives in the application universe where all references between modules are already resolved. In CLI and in PostSharp, references are explicitly represented as separate entities. But in System.Reflection, there is simply no concept of reference.

Modules

Modules (ModuleDeclaration) are atomic artifacts (i.e. they cannot be separated in smaller units). .NET modules are in fact Portable Executables (PE) just like native libraries and executables.

Assemblies

There is a common confusion about assemblies. An assembly, as indicated by its name, is a set of assembled modules and other files. So an assembly can be composed of many modules and even of unmanaged modules! It is a common mistake and misleading to consider that an assembly is composed of a single file.

What defines intrinsically the assembly is its assembly manifest (AssemblyManifestDeclaration). The manifest is composed of a list of references to modules and external assemblies, and of a list of exported types. The assembly manifest is contained in 'principal' managed module of the assembly (and not in a separate XML file, as claims another frequent mistake).

So the assembly manifest (AssemblyManifestDeclaration) is contained in a module (ModuleDeclaration); it contains references to external modules (ModuleRefDeclaration) and external assemblies (AssemblyRefDeclaration).

So let's summarize:

  • Modules, not assemblies, are the real atoms.
  • Assemblies are composed of many modules (managed or unmanaged executables).
  • Assemblies are defined by an assembly manifest.
  • The assembly manifest is stored in a managed module.
  • A managed module may, but is not required to, contain an assembly manifest.

PostSharp makes a difference between an assembly and an assembly manifest. The AssemblyEnvelope class encapsulates the assembly understood as a collection of modules. The AssemblyManifestDeclaration class encapsulates the manifest; it does not contain modules but is contained by a module. Where AssemblyManifestDeclaration contains a collection of references to modules, AssemblyEnvelope contain modules in themselves.

Domains

PostSharp domains (Domain) are similar to the .NET class AppDomain. Domains are contexts in which references between assemblies are solved. Just as in .NET, PostSharp assemblies are always loaded in a domain. PostSharp allows many domains to be loaded paralelly, even in the same AppDomain.

The base of the object tree is the ModuleDeclaration type. Since PostSharp is module-oriented, everything is contained in the module even the assembly manifest.

posted @ 2008-12-10 12:24 Andrew Yin 阅读(2962) 评论(10) 编辑

2008年12月8日

今天看了RednaxelaFX的一系列关于LINQ与DLR的Expression tree, 收益非浅,很久没有读到这么让人痛快淋漓的有技术深度的文章了! 园子里很多文章的内容都不深入(包括一些MVP写的系列教程),似乎都类似Scottu Gu的博客内容,针对的是初学者.当然, 我并没有认为那些人写的东西不好,他们花了不少时间和精力,文字功底也很不错,为初学者提供了很好的学习资源.(如Terry Lee,Jeffrey),他们人都很好,大家都很忙,很少有人愿意花时间写那么多的文字供其它人学习的. 感谢他们.

在RednaxelaFX的一系列文章中,我看到了一个研究者的写作态度.他的知识面很广,写起文章来,旁征博引,娓娓道来,又有深度,需要读者深入研究和查阅一定的资料才能明白过来.有点国外某些编程语言创始人或者编译器开发人员的姿态!

例如:他对AST,DLR tree,CCI的介绍,对.NET平台下动态语言支持的原理的研究. 可以看出作者阅读了大量的资料,才能知旁人所不知,作出有一定深度的文章.作者的研究态度值得我们学习.

贴出牛人的关于Expression Tree的系列文章的链接:

LINQ与DLR的Expression tree(1):简介LINQ与Expression tree
LINQ与DLR的Expression tree(2):简介DLR
LINQ与DLR的Expression tree(3):LINQ与DLR及另外两个库的AST对比
LINQ与DLR的Expression tree(4):创建静态类型的LINQ表达式树节点
LINQ与DLR的Expression tree(5):用lambda表达式表示常见控制结构

posted @ 2008-12-08 23:19 Andrew Yin 阅读(2506) 评论(29) 编辑

http://tirania.org/blog/(Mono创始者的blog)上的一个POST上说Moon现在有一个交互式的C# Shell,允许像执行Javascript eval那样执行C#

例子:

  1. csharp> 1;    
  2. 1    
  3. csharp> "Hello, World".IndexOf (",");    
  4. 5    
  5. csharp> Console.WriteLine ("Hello");    
  6. Hello   

posted @ 2008-12-08 14:08 Andrew Yin 阅读(149) 评论(0) 编辑

2008年12月5日

posted @ 2008-12-05 18:00 Andrew Yin 阅读(951) 评论(1) 编辑

posted @ 2008-12-05 15:46 Andrew Yin 阅读(880) 评论(1) 编辑

posted @ 2008-12-05 14:39 Andrew Yin 阅读(1001) 评论(0) 编辑