数字键盘输入法——崩出来的“猪”字的背后

    是否还记得去年流行的一个“神秘”的小把戏?就是在MSNQQ之类的IM工具的消息输入框里,按下键盘上的ALT键,然后在键盘的数字区域打入29482,然后再松开ALT键,然后一个“猪”字就崩了出来?当时有好几个人发了mail告诉我这个小把戏,我马上有了兴趣,于是查了点资料想解开背后的原因。然后用JAVA写了个小程序,输入一个字符串,然后输出这种神秘输入法的“编码”。今天重新翻了出来,改写成了C#版。

 

    事实上,很容易知道,29482就是“猪”字的UNICODE编码的十进制值,十六进制值是/u 732A ,马上就没有了悬念,对于像JAVA.NET平台,十分容易就可以获取到字符的UNICODE编码值,因为其本身就是用宽字符存储char型数据的,而且有直接的API可以调用。甚至最简单的,用(int)char强制转换,就可以得到字符的UNICODE编码十进制值。不过这里讲的程序还是不那么做,先获取字符的两个字节,然后再自己转换。

 

    当然,如果光是UNICODE编码,就太没有意思了,于是还顺便做了扩展ASCII编码的获取方法,当然是针对汉字gb2312编码的,这也是简体中文系统的默认编码。这种“输入法”其实跟IM工具毫无关系,似乎就是操作系统开放的一个功能,只是大家没察觉而已,之所以网上流行的说法都是MSNQQ里输入,是因为这两个工具的字符存储是UNICODE的,所以,事实上所有UNICODE存储的软件都可以用这种输入法,比如MS Office Word,比如以UNICODE存储方式运行的记事本程序(Windows记事本默认是以ASCII编码存储的,但可以用另存为,选择一种字符编码)。那么,对于ASCII编码呢?其实找到了ASCII编码,一样可以使用这种方式输入,双字节语言比如汉语、日语、韩语都可以用扩展ASCII编码存储,都容易获取其编码。

 

    好了,不多说了,直接贴代码了,程序很短,也没什么难点,简单说明一下WordDecode类,用一个UNICODE字符构造该类的实例,然后用属性直接获取到相应的编码。

 

1. WordEncode

 

     /// <summary>
    
/// 字符编码获取
    
/// </summary>

     class  WordDecode
    
{       
        
private byte highByteUni;
        
private byte lowByteUni;
        
private byte highByteEAscii;
        
private byte lowByteEAscii;

        
private static Encoding eeas = System.Text.ASCIIEncoding.GetEncoding("gb2312");
        
private static Encoding euni = System.Text.UnicodeEncoding.Unicode;

        
public byte HighByteUni
        
{
            
get return highByteUni; }
            
set { highByteUni = value; }
        }


        
public byte LowByteUni
        
{
            
get return lowByteUni; }
            
set { lowByteUni = value; }
        }


        
/// <summary>
        
/// Unicode编码十六进制形式
        
/// </summary>

        public string UnicodeAsHex
        
{
            
get
            
{               
                
if( highByteUni != 0)
                    
return String.Format("/u{0:X}{1:X}", highByteUni, lowByteUni);
                
return String.Format("/u{0:X}", lowByteUni);
            }

        }


        
public byte HighByteEAscii
        
{
            
get return highByteEAscii; }
            
set { highByteEAscii = value; }
        }


        
public byte LowByteEAscii
        
{
            
get return lowByteEAscii; }
            
set { lowByteEAscii = value; }
        }


        
/// <summary>
        
/// EAscii编码十六进制形式(gb2312)
        
/// </summary>

        public string EAsciiAsHex
        
{
            
get
            
{
                
if( highByteEAscii !=0)
                    
return String.Format("/0x{0:X}{1:X}", lowByteEAscii, highByteEAscii);
                
return String.Format("/0x{0:X}", lowByteEAscii);
            }

        }


        
/// <summary>
        
/// 数字键盘Unicode编码的十进制值
        
/// </summary>

        public string KeyboardNumAreaUnicodeValue
        
{
            
//20013 -> 78(High)  45(Low)     
            
//         1001110   00101101            
            
//就是"中"字
            get
            
{
                
int u = 0;
                u 
|= this.highByteUni;
                u 
<<= 8;
                u 
|= this.lowByteUni;
                
return u.ToString();
            }

        }


        
/// <summary>
        
/// 数字键盘EAscii编码的十进制值(gb2312)
        
/// </summary>

        public string KeyboardNumAreaEAsciiValue
        
{
            
//54992 -> 208(High)  214(low)       
            
//         11010000   11010110              
            
//就是"中"字
            get
            
{
                
int u = 0;
                u 
|= this.lowByteEAscii;
                u 
<<= 8;
                u 
|= this.highByteEAscii;
                
return u.ToString();
            }

        }


        
/// <summary>
        
/// 原字符(Unicode编码)
        
/// </summary>

        public Char CharacterUni
        
{
            
get
            
{
                
return euni.GetChars(new byte[] this.lowByteUni, this.highByteUni })[0];
            }

        }


        
/// <summary>
        
/// 构造函数
        
/// </summary>
        
/// <param name="uniChar">一个16位宽字符</param>

        public WordDecode(char uniChar)
        
{
            
byte[] bsUni = euni.GetBytes(new char[] { uniChar });
            
this.highByteUni = bsUni[1];
            
this.lowByteUni = bsUni[0];
            
byte[] bsEAs = eeas.GetBytes(new char[] { uniChar });
            
if (bsEAs.Length == 2)
            
{
                
this.highByteEAscii = bsEAs[1];
                
this.lowByteEAscii = bsEAs[0];
            }

            
else
                
this.lowByteEAscii = bsEAs[0];
        }


        
/// <summary>
        
/// 构造函数
        
/// </summary>
        
/// <param name="highByteUni">Unicode高位字节</param>
        
/// <param name="lowByteUni">Unicode低位字节</param>

        public WordDecode(byte highByteUni, byte lowByteUni)
        
{
            
this.highByteUni = highByteUni;
            
this.lowByteUni = lowByteUni;
        }

    }

 

2. Console中的测试程序

 

  class  Program
    {
        
static   void  Main( string [] args)
        {
            WordDecode[] wes 
=  GetEncodeString( " 猪——数字键盘输入法123ABCabc. " );
            
foreach  (WordDecode we  in  wes)
            {
                Console.WriteLine(
" {0} -> {1}, {2}   KUnicode: {3}, KEAscii: {4} "
                    we.CharacterUni ,we.UnicodeAsHex, we.EAsciiAsHex , 
                    we.KeyboardNumAreaUnicodeValue, we.KeyboardNumAreaEAsciiValue);
            }

            Console.ReadLine();
        }

        
///   <summary>
        
///  获取字符串的所有字符的数字键盘输入法编码
        
///   </summary>
        
///   <param name="input"> 输入字符串 </param>
        
///   <returns></returns>
         static  WordDecode[] GetEncodeString( string  input)
        {
            System.Collections.ArrayList arr 
=   new  System.Collections.ArrayList();
            
char [] chars  =  input.ToCharArray();
            
foreach  ( char  c  in  chars)
            {
                arr.Add(
new  WordDecode(c));
            }             
            
return  (WordDecode[])arr.ToArray( typeof (WordDecode));
        }
    }

 

 3.  测试程序的输出:

 

猪 -> /u732A, /0xD6ED   KUnicode: 29482, KEAscii: 55021
— -> /u2014, /0xA1AA   KUnicode: 8212, KEAscii: 41386
— -> /u2014, /0xA1AA   KUnicode: 8212, KEAscii: 41386
数 -> /u6570, /0xCAFD   KUnicode: 25968, KEAscii: 51965
字 -> /u5B57, /0xD7D6   KUnicode: 23383, KEAscii: 55254
键 -> /u952E, /0xBCFC   KUnicode: 38190, KEAscii: 48380
盘 -> /u76D8, /0xC5CC   KUnicode: 30424, KEAscii: 50636
输 -> /u8F93, /0xCAE4   KUnicode: 36755, KEAscii: 51940
入 -> /u5165, /0xC8EB   KUnicode: 20837, KEAscii: 51435
法 -> /u6CD5, /0xB7A8   KUnicode: 27861, KEAscii: 47016
1 -> /u31, /0x31   KUnicode: 49, KEAscii: 12544
2 -> /u32, /0x32   KUnicode: 50, KEAscii: 12800
3 -> /u33, /0x33   KUnicode: 51, KEAscii: 13056
A -> /u41, /0x41   KUnicode: 65, KEAscii: 16640
B -> /u42, /0x42   KUnicode: 66, KEAscii: 16896
C -> /u43, /0x43   KUnicode: 67, KEAscii: 17152
a -> /u61, /0x61   KUnicode: 97, KEAscii: 24832
b -> /u62, /0x62   KUnicode: 98, KEAscii: 25088
c -> /u63, /0x63   KUnicode: 99, KEAscii: 25344
. -> /u2E, /0x2E   KUnicode: 46, KEAscii: 11776

 

 

    好了,用这个程序,就可以用这种神秘输入法输入任何汉字字符了,在UNICODE环境里,按住ALT键,在键盘数字区域键入相应的KUnicode值,就会打出你要的字符了,在ASCII环境,用同样的方法键入相应的KEAscii值也会输出同样的字符(最简单的,可以在IE的地址栏栏里试试,它是ASCII的,当然默认的记事本存储文件也是)。不过如果你想用笔记本试试这种输入法,那就不行了,因为笔记本键盘一般都没有数字键盘区域。

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值