我正在嘗試從以下注冊表項中獲取產品密鑰/ID:
SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion
Key: DigitalProductId
然而,它的編碼方式在java中還沒有被解碼。我可以使用 JNA 檢索位元組陣列,但無法對其進行解碼。
這是解碼器的 C# 實作:
string key = String.Empty;
const int keyOffset = 52;
byte keyBytes = (byte)((digitalProductId[66] / 6) & 1);
digitalProductId[66] = (byte)((digitalProductId[66] & 0xf7) | (keyBytes & 2) * 4);
const string digits = "BCDFGHJKMPQRTVWXY2346789";
var last = 0;
for (var i = 24; i >= 0; i--)
{
var current = 0;
for (var i2 = 14; i2 >= 0; i2--)
{
current *= 256;
current = digitalProductId[i2 keyOffset] current;
digitalProductId[i2 keyOffset] = (byte)(current / 24);
current %= 24;
last = current;
}
key = digits[current] key;
}
string keypart1 = key.Substring(1, last);
string keypart2 = key.Substring(last 1, key.Length - (last 1));
key = keypart1 "N" keypart2;
for (var i3 = 5; i3 < key.Length; i3 = 6)
{
key = key.Insert(i3, "-");
}
systemInformation.ProductKey = key;
return systemInformation;
當我嘗試使用以下實作將其移植到 Java 時(FXStringUtil 是我創建的具有插入功能的類):
String key = "";
int keyOffset = 52;
byte keyBytes = (byte) ((digitalProductId[66] / 6) & 1);
digitalProductId[66] = (byte) ((digitalProductId[66] & 0xf7) | (keyBytes & 2) * 4);
String digits = "BCDFGHJKMPQRTVWXY2346789";
int last = 0;
for (int i = 24; i >= 0; i--) {
int current = 0;
for (int i2 = 14; i2 >= 0; i2--) {
current *= 256;
current = digitalProductId[i2 keyOffset] current;
digitalProductId[i2 keyOffset] = (byte) (current / 24);
current %= 24;
last = current;
}
key = digits.charAt(current) key;
}
String keypart1 = key.substring(1, last);
String keypart2 = key.substring(last 1, key.length() - (last 1));
key = keypart1 "N" keypart2;
for (int i3 = 5; i3 < key.length(); i3 = 6) {
key = FXStringUtil.insertString(key,"-", i3);
}
return key;
我在包含以下內容的行上收到錯誤訊息:
key = digits.charAt(current) key;
其中如下:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -15
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48)
at java.base/java.lang.String.charAt(String.java:712)
at lol.foxxy.idfkwasbored.util.KeyUtil.DecodeProductKeyWin8AndUp(KeyUtil.java:60)
at lol.foxxy.idfkwasbored.util.KeyUtil.getProductKey(KeyUtil.java:31)
at lol.foxxy.idfkwasbored.Main.main(Main.java:123)
這個錯誤在C#實作中不會出現,所以我想知道為什么會出現這個錯誤。我把它固定在這一行(我認為是導致問題的原因):
current = digitalProductId[i2 keyOffset] current;
但是,我不知道究竟是哪一部分可能導致了問題。
uj5u.com熱心網友回復:
C# 和 Java 之間有兩個主要區別會導致您的 Java 代碼無法運行。
第一個是在 C# 中 abyte是無符號的,而在 Java 中 abyte是有符號的。
這確實會導致您在問題中指出的問題:
current = digitalProductId[i2 keyOffset] current;
在 Java 中,digitalProductId[i2 keyOffset],因此也是digitalProductId[i2 keyOffset] current,可能是負數。這些負數將導致StringIndexOutOfBoundsException您得到的s。
修復您的 Java 代碼是確保digitalProductId[i2 keyOffset]在上面的行中被轉換為int0 到 255 范圍內的一個。 最簡單的方法是執行按位與0xFF:
current = (digitalProductId[i2 keyOffset] & 0xFF) current;
另一個區別是在 Java 中,to 的第二個引數String.substring(int,int)是結束索引(更準確地String.substring(startIndex, endIndex)回傳從 indexstartIndex到 index的子字串endIndex - 1)。但是,在 C# 中,第二個引數 toString.Substring(Int32,Int32)是子字串的長度。
因此,提取密鑰部分的兩行應如下所示:
String keypart1 = key.substring(1, last 1); // not .substring(1, last)
String keypart2 = key.substring(last 1);
請注意,對于第二行,我使用了它的單引數多載String.substring,它只采用起始索引并將字串從那里回傳到字串的末尾。實際上,您可以對 C# 代碼進行相同的修改:
string keypart2 = key.Substring(last 1);
我沒有任何代碼來獲取產品密鑰,所以我編造了一些隨機位元組,并在這個編造的資料上運行了 C# 和修改的 Java 代碼,兩個程式都回傳了相同的輸出。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/392764.html
