2015-10-04 41 views
0

我想確保對嚴格正數多頭的異或操作只產生嚴格正數的多頭頭寸。確保對嚴格正數的長期異或操作只能產生嚴格正數多頭頭寸

我的問題是底座上的Java代碼:

import java.nio.ByteBuffer; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.ListIterator; 
import java.util.Random; 

public class Test { 

    static Random r = new Random(); 

    static class Data { 
     long id = Math.abs(r.nextLong()); 

     @Override 
     public String toString() { 
      return "Data {" + "id=" + id + '}'; 
     } 
    } 

    public static void main(String[] args) { 
     List<Data> data = new ArrayList<>(); 
     for (int i = 0; i < 10; i++) { 
      data.add(new Data()); 
     } 

     final String password = "don't you ever tell them"; 

     byte[] passwordBytes = password.getBytes(); 
     long[] passwordLongs = new long[passwordBytes.length/8]; 

     for (int i = 0; i < passwordLongs.length; i++) { 
      ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); 
      byte[] chunk = new byte[Long.BYTES]; 
      System.arraycopy(passwordBytes, i * Long.BYTES, chunk, 0, Long.BYTES); 
      buffer.put(chunk); 
      buffer.flip();//need flip 
      passwordLongs[i] = buffer.getLong(); 
     } 

     System.out.println(data); 

     ListIterator<Data> encryptIterator = data.listIterator(); 
     while (encryptIterator.hasNext()) { 
      Data next = encryptIterator.next(); 
      next.id = next.id^passwordLongs[(encryptIterator.nextIndex() - 1) % passwordLongs.length];//XOR here 
     } 

     System.out.println(data); 
    } 
} 

誰能請提供可能的答案與一些理論?

+0

你的問題與你的代碼有什麼關係? – immibis

+0

另外,你確定這是一個有用和安全的方式來處理密碼? (我假設它*應該*是有用和安全的) – immibis

+0

@immibis:我當然不會存儲上面顯示的密碼。 :-) – balteo

回答

2
  • 不變量1:正整數的最高有效位爲零。

  • 不變2:0 XOR 0 = 0

結論:正整數XOR正整數=正整數。

+0

我不確定你的意思是不變的1.'Long.toBinaryString(i)'總是以** 1 **開頭的正數。這是最重要的一點嗎? – balteo

+1

正如Javadoc所解釋的那樣:'該值在二進制(基2)中被轉換爲一串ASCII數字,沒有額外的前導0。輸出一個從零開始的字符串是不可能的(除非數字本身爲零)。順便說一下,「最重要的位」是與「long」中的位數63相關的。 –

+1

絕對不能轉換爲字符串。使用測試'(i&(1 << 63))== 1'。這使MSB = 1成爲「真」,MSB = 0成爲「假」。 –

1

鑑於Java中的longs總是被簽名的,你應該確保你的「密碼」中的每個long都不會切換符號位。

也就是說,您所在的password中的所有long都應該像0b0xxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx一樣。

這會削弱「加密」(正好)一點,但您不應該擔心這一點。

但應該注意的是,除非你想比較它們是否大於0,否則沒有理由這麼做;實際的數字將始終相同,即0xff0b11111111始終相同,只有其十進制表示根據是使用無符號還是有符號短整數來存儲它(分別爲255-1)而變化。

+0

要在Java 8(1.8.x)中添加,您似乎還沒有簽名很長。 – Victor