糊言乱语

志未半斤, 才无八两. 有苦有乐, 糊涂过活。
posts - 25, comments - 7, trackbacks - 0, articles - 42
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2008年7月11日

image

posted @ 2008-07-11 11:25 Stanley Sun 阅读(317) | 评论 (0)编辑 收藏

2008年6月14日

众所周知在计算机中所有的数据都是以二进制的方式存储的。不管是int,String,float等等不同的数据类型,最终都会保存为01的形式。那么为什么要使用这种方式储存数据呢?

因为计算机是一种电子设备,由复杂的电子元器件组合而成,一个电子元器件有带电和不带电两种状态,通常我们将带电状态表示为数值1,不带电状态表示为数值0,多个这样的元器件的组合可以表示更多状态,也就是可以表示更多的数据,如000表示0,001表示1,010表示2,011表示3,依此类推,111表示 7,一个元器件可表示一位(bit)数据,这种表示数据的方式就叫二进制。
在实际的电子设备中,我们将8个这样的元器件形成一个单元,这样的单元叫一个字节(byte),一个字节能表示多少个数呢?表示数值的范围是0-255。
一个字节由8个二进位组成,其中最右边的一位称为“最低有效位”或“最低位”,最左边的一位称为“最高有效位”或“最高位”。每一个二进位的值是0或1。

二进制计数的缺点:书写太长,容易出错,一般计算机的数据位数都是4的整数倍,所以,在计算机里通常采用16进制计数法。用数字可以表示各种信息,计算机里只有数值,当你在内存中看到一个数值时,这个数值可能代表各种意义,生活中的数值也可以代表其他意义,如1234可以代表密码,存款额,电报信息,根据上下线索,我们就能够知道这数值代表的意义

 

但是在Java中到底是如何去保存数据的呢?下面我就以int数据类型为例说明Java的方式。

大家都知道在Java中规定1 int = 4 byte, 1 byte = 8 bit。以此推理那么1个int在计算机中就是以4 * 8 = 32位(bit)的方式存储的。而又由于java中的int是属于有符号类型(Java中不存在unsigned类型),所以32位的高一位是符号位,由此可以推理出int的储存大小区间

Integer.MAX_VALUE = 2147483647(十进制) = 1111111 11111111 11111111 11111111(二进制)
Integer.MIN_VALUE = -2147483648(十进制) = 10000000 00000000 00000000 00000000(二进制)

现在我们知道了二进制的概念了,但是其实二进制我想我们想象的那么单纯的表示的,他们是不同的表现方式如:原码,反码,补码

  • 原码
    将最高位作为符号位(以0代表正,1代表负),其余各位代表数值本身的绝对值(以二进制表示)。
                为了简单起见,我们用1个字节来表示一个整数。
                +7的原码为: 00000111
                 -7的原码为: 10000111
  • 反码
          一个数如果为正,则它的反码与原码相同;一个数如果为负,则符号位为1,其余各位是对原码取反。
                为了简单起见,我们用1个字节来表示一个整数。
                +7的反码为: 00000111
                 -7的反码为: 11111000
  • 补码
        利用溢出,我们可以将减法变成加法。
        对于十进制数,如果从9得到结果5,可以用减法:
             9-4=5
          因为4+6=10,我们将6作为4的补数,将上式的减法改写为加法:
             9+6=15
          去掉高位1(也就是减去10),得到结果5。
          对于16进制数,如果从C得到结果5,可以用减法:
             C-7=5
          因为7+9=16,我们将9作为7的补数,将上式的减法改写为加法:
             C+9=15
          去掉高位1(也就是减去16),得到结果5。
          在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为:
               1 00000000
        进位1被丢弃。
        一个数如果为正,则它的原码、反码、补码相同;一个数如果为负,则符号位为1,其余各位是对原码取反,然后整个数加1。
                为了简单起见,我们用1个字节来表示一个整数。
                +7的补码为: 00000111
                -7的补码为:第一步:11111000 (符号位为,其余各位取反)
                                      第二步:11111001 (整个数加1)
               +0的补码:00000000;
               -0的补码:11111111;(第一步)
                              100000000;(第二步)
    已知一个负数的补码,将其转换为十进制数,步骤:
          1、先对各位取反;
          2、将其转换为十进制数;
          3、加上负号,再减去1。
          例如:
          11111010,最高位为1,是负数,先对各位取反得00000101,转换为十进制数得5,加上负号得-5,再减1得-6。
  •  

    那么我们就知道了1与-1的二进制形式分别为0000000 00000000 00000000 00000001和11111111 11111111 11111111 11111111(Java中的数据是以补码的形式储存的)了。那么现在我们知道了数据是如何储存的了。那么计算机是如何利用这些数据进行计算的呢?我们知道在计算机的CPU中只有一个加法器,所有的运算都是需要它进行的。所以在计算机里所有的加减乘除都是转换成加法来进行运算的。那么它们是怎么转换的呢?下面我们介绍一下二进制的运算操作

  • 位运算符
    为了方便对二进制位进行操作,Java给我们提供了四个二进制位操作符:
    &          按位与
    |           按位或
    ^          按位异或
    ~          按位取反
  • 按位
        一个房间里有两个开关控制房间的灯的明暗。当两个开关同时处于打开状态时,灯才能亮。
         开关1                   开关2                         灯的状态
           关                         关                              暗
          开                          关                              暗
          关                          开                              暗
          开                          开                              亮
    结论:按位与,只有壹(1)壹(1)为1。
  • 按位
        一个房间里有两个开关控制房间的灯的明暗。当任何一个开关处于打开状态时,灯就能亮。
        开关1                     开关2                     灯的状态
           关                         关                              暗
          开                          关                              亮
          关                          开                              亮
          开                          开                              亮
    结论:按位或,只有零(0)零(0)为0。
  • 按位异或
        一个房间里有两个开关控制房间的灯的明暗。当两个开关处于不同状态时,灯就能亮。
       开关1                    开关2                       灯的状态
          关                          关                              暗
          开                          关                              亮
          关                          开                              亮
          开                          开                              暗
    结论:按位异或,只有零(0)壹(1)或壹(1)零(0)为1。
  • 按位取反
    结论:对二进制数按位取反,即0变成1,1变成0。
  • Java中有三个移位运算符
    左移:<<              (相当于 乘以2)
    带符号右移:>>     (相当于 除以2)
    无符号右移:>>>
      数            x                   x<<2                 x>>2              x>>>2
    17      00010001    00 01000100      00000100 01     00000100 01
    -17     11101111     11 10111100      11111011 11     00111011 11
  • posted @ 2008-06-14 15:25 Stanley Sun 阅读(1050) | 评论 (0)编辑 收藏

    2007年12月5日

    概念:

    1.数字摘要:解决在安全的通信环境下,保证信息的唯一的一种方式。通常使用MD5/SHA-1等算法完成摘要。一般比如大家在网上下载软件光盘时都会看到一个MD5值就是起到这个数字摘要的作用。在网络的环境中发送者把消息和数字摘要一同发送给接收者,接收者使用发送者相同的算法对消息加密,看是否与发送者发送过来的数字摘要相同,如果相同就证明消息没有给篡改过。下面是一个最为简单的示例:

    import java.security.*;
    public class myDigest {
      public static void main(String[] args)  {
        myDigest my=new myDigest();
        my.testDigest();
      }
      public void testDigest()
      {
       try {
         String myinfo="我的测试信息";
        //java.security.MessageDigest alg=java.security.MessageDigest.getInstance("MD5");
          java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");
          alga.update(myinfo.getBytes());
          byte[] digesta=alga.digest();
          System.out.println("本信息摘要是:"+byte2hex(digesta));
          //通过某中方式传给其他人你的信息(myinfo)和摘要(digesta) 对方可以判断是否更改或传输正常
          java.security.MessageDigest algb=java.security.MessageDigest.getInstance("SHA-1");
          algb.update(myinfo.getBytes());
          if (algb.isEqual(digesta,algb.digest())) {
             System.out.println("信息检查正常");
           }
           else
            {
              System.out.println("摘要不相同");
             }
       }
       catch (java.security.NoSuchAlgorithmException ex) {
         System.out.println("非法摘要算法");
       }
      }
      public String byte2hex(byte[] b) //二行制转字符串
        {
         String hs="";
         String stmp="";
         for (int n=0;n<b.length;n++)
          {
           stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
           if (stmp.length()==1) hs=hs+"0"+stmp;
           else hs=hs+stmp;
           if (n<b.length-1)  hs=hs+":";
          }
         return hs.toUpperCase();
        }
    }
    

    2.电子签名:对数据信息的发生者身份的认定,它是一种抽象的概念而不是一种具体技术。实现电子签名的技术手段目前有多种,比如基于公钥密码技术的数字签名;或用一个独一无二的以生物特征统计学为基础的识别标识,例如手印、声音印记或视网膜扫描的识别;手书签名和图章的电子图象的模式识别;表明身份的密码代号(对称算法);基于量子力学的计算机等等。


    3.数字签名:所谓数字签名就是利用通过某种密码运算生成的一系列符号及代码组成电子密码进行"签名",来代替书写签名或印章,对于这种电子式的签名在技术上还可进行算法验证,其验证的准确度是在物理世界中与手工签名和图章的验证是无法相比的。一般实现数字签名的方法是通过生成的密钥对的私钥对用户生成的数字消息进行DSA(Digital Signature Algorithm (DSA)是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard))加密实现的。实现代码如下:

       */
     import java.security.*;
     import java.security.spec.*;
    public class testdsa {
      public static void main(String[] args) throws java.security.NoSuchAlgorithmException,java.lang.Exception {
            testdsa my=new testdsa();
            my.run();
      }
      public void run()
      {
      //数字签名生成密钥
      //第一步生成密钥对,如果已经生成过,本过程就可以跳过,对用户来讲myprikey.dat要保存在本地
      //而mypubkey.dat给发布给其它用户
       if ((new java.io.File("myprikey.dat")).exists()==false) {
           if (generatekey()==false) {
               System.out.println("生成密钥对败");
               return;
              };
            }
    //第二步,此用户
    //从文件中读入私钥,对一个字符串进行签名后保存在一个文件(myinfo.dat)中
    //并且再把myinfo.dat发送出去
    //为了方便数字签名也放进了myifno.dat文件中,当然也可分别发送
      try {
      java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat"));
      PrivateKey myprikey=(PrivateKey)in.readObject();
      in.close();
     // java.security.spec.X509EncodedKeySpec pubX509=new java.security.spec.X509EncodedKeySpec(bX509);
     //java.security.spec.X509EncodedKeySpec pubkeyEncode=java.security.spec.X509EncodedKeySpec
      String myinfo="这是我的信息";    //要签名的信息
      //用私钥对信息生成数字签名
      java.security.Signature signet=java.security.Signature.getInstance("DSA");
      signet.initSign(myprikey);
      signet.update(myinfo.getBytes());
      byte[] signed=signet.sign();  //对信息的数字签名
      System.out.println("signed(签名内容)="+byte2hex(signed));
     //把信息和数字签名保存在一个文件中
      java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat"));
      out.writeObject(myinfo);
      out.writeObject(signed);
      out.close();
      System.out.println("签名并生成文件成功");
      }
      catch (java.lang.Exception e) {
        e.printStackTrace();
        System.out.println("签名并生成文件失败");
      };
      //第三步
      //其他人通过公共方式得到此户的公钥和文件
      //其他人用此户的公钥,对文件进行检查,如果成功说明是此用户发布的信息.
      //
      try {
       java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat"));
       PublicKey pubkey=(PublicKey)in.readObject();
       in.close();
       System.out.println(pubkey.getFormat());
       in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat"));
       String info=(String)in.readObject();
       byte[] signed=(byte[])in.readObject();
       in.close();
      java.security.Signature signetcheck=java.security.Signature.getInstance("DSA");
      signetcheck.initVerify(pubkey);
      signetcheck.update(info.getBytes());
      if (signetcheck.verify(signed)) {
      System.out.println("info="+info);
       System.out.println("签名正常");
      }
      else  System.out.println("非签名正常");
      }
      catch (java.lang.Exception e) {e.printStackTrace();};
      }
      //生成一对文件myprikey.dat和mypubkey.dat---私钥和公钥,
      //公钥要用户发送(文件,网络等方法)给其它用户,私钥保存在本地
      public boolean generatekey()
      {
        try {
      java.security.KeyPairGenerator  keygen=java.security.KeyPairGenerator.getInstance("DSA");
     // SecureRandom secrand=new SecureRandom();
     // secrand.setSeed("tttt".getBytes()); //初始化随机产生器
     // keygen.initialize(576,secrand);     //初始化密钥生成器
      keygen.initialize(512);
      KeyPair keys=keygen.genKeyPair();
    //  KeyPair keys=keygen.generateKeyPair(); //生成密钥组
      PublicKey pubkey=keys.getPublic();
      PrivateKey prikey=keys.getPrivate();
      java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat"));
      out.writeObject(prikey);
      out.close();
      System.out.println("写入对象 prikeys ok");
      out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat"));
       out.writeObject(pubkey);
       out.close();
       System.out.println("写入对象 pubkeys ok");
       System.out.println("生成密钥对成功");
       return true;
      }
      catch (java.lang.Exception e) {
       e.printStackTrace();
       System.out.println("生成密钥对失败");
       return false;
       };
      }
      public String byte2hex(byte[] b)
        {
         String hs="";
         String stmp="";
         for (int n=0;n<b.length;n++)
          {
           stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
           if (stmp.length()==1) hs=hs+"0"+stmp;
           else hs=hs+stmp;
           if (n<b.length-1)  hs=hs+":";
          }
         return hs.toUpperCase();
        }
    }    把他的公钥的信息及签名发给其它用户
    


    4.PKI(公钥基础设施):

    posted @ 2007-12-05 22:09 Stanley Sun 阅读(522) | 评论 (1)编辑 收藏

    2007年12月3日

    安装完成之后打开window->show views-Task Repositories,界面如下图:


    在空白处右键点击add task repository添加知识库,如图:

    选中Jira,下一步:


    server中填写Jira的地址(http://ycfd.3322.org:88/jira),label随便填写,User ID和Password就是你在Jira上注册的帐号和密码了,填写完毕之后点Validate Setting,验证成功之后点完成即可。

    在添加完repository后,会弹出添加query界面。如图:

    选择create query using form后点击next,进入query设置界面,如图:


    在project中选中fms后点击finish。这样就完成了各项设置
    之后打开tasklist视图:window->show view->other->mylyn->task list

    点击OK,后打开task list视图,如图:


    在Task List中你可以看到你的项目中的问题和任务等,双击Task会显示该Task的详细情况:

    在Task List中还能新建Task并提交到Jira,这里就不多说了,大家自己尝试一下。

    posted @ 2007-12-03 16:38 Stanley Sun 阅读(1337) | 评论 (0)编辑 收藏

    mylyn是一款开源的基于eclipse开发平台的任务管理组件,可以制定自己的本地任务及在远程服务器(其中包括Bugzilla、Trac 和 JIRA等)中的远程任务。对于我们现在的项目,使用mylyn就可以方便我们直接的浏览在JIRA中的任务,而不必经常的登录JIRA平台了。提高了大家的工作效率。

    由于mylyn与在我们现在在项目中使用的eclipse开发平台中springide插件有冲突问题,所以首先大家需要把springide插件从eclipse中卸载。步骤如下:

    1.在eclipse安装目录下找到一个名为links的文件夹,在这个文件夹中删除Springide.link文件。

    2.启动eclipse,不过与平常不同的是需要在eclipse启动命令中加入-clean参数。可以直接加入到eclipse快捷方式的目标项中。

    此时eclipse会把springide插件卸载,之后我们就可以安装mylyn插件了。在开始安装mylyn之前,大家需要下载附件中的如下三个文件:mylyn-2.1-e3.3.zip,mylyn-2.1-extras.zip,springide_updatesite_2.0.1_v200708152145.zip

    步骤如下:

    1.设置本地插件归档:进入help->software updates->find and install菜单后,选择search for new features to install后点击next

    进入install界面,如下图:


    把下载的三个zip归档加入后,点击finish.

    2.在弹出的updates窗口中选中刚才加入的三个归档,并把springide->integrations->spring ide ajdt integrations去掉后,如下图:

    之后进入授权界面,选择i accept后next,如图:

    3.在弹出的verification窗口中点击install all开始安装,如图:

    之后提示是否重启eclipse,点击是。

    posted @ 2007-12-03 16:38 Stanley Sun 阅读(5498) | 评论 (0)编辑 收藏