سؤال

لدي مصفوفة بايت SHA-1 أرغب في استخدامها في طلب GET.أحتاج إلى ترميز هذا. URLEncoder تتوقع سلسلة، وإذا قمت بإنشاء سلسلة منها ثم قمت بتشفيرها، فإنها تفسد؟

للتوضيح، هذا نوعاً ما متابعة لسؤال آخر لي.(طلب تعقب تورنت) يمكنني الحصول على القيمة كسلسلة سداسية عشرية، لكن لم يتعرف المتتبع على ذلك.ومن ناحية أخرى، فإن علامة الإجابة المشفرة بشرط إرجاع 200 موافق.

لذلك أحتاج إلى تحويل التمثيل السداسي الذي حصلت عليه:

9a81333c1b16e4a83c10f3052c1590aadf5e2e20

في شكل مشفرة

%9A%813%3C%1B%16%E4%A8%3C%10%F3%05%2C%15%90%AA%DF%5E.%20
هل كانت مفيدة؟

المحلول

تم تحرير السؤال أثناء الرد، فيما يلي رمز إضافي ويجب أن يعمل (مع رمز التحويل السداسي الخاص بي):

//Inefficient, but functional, does not test if input is in hex charset, so somewhat unsafe
//NOT tested, but should be functional
public static String encodeURL(String hexString) throws Exception {
  if(hexString==null || hexString.isEmpty()){
     return "";
  }
  if(hexString.length()%2 != 0){
    throw new Exception("String is not hex, length NOT divisible by 2: "+hexString);
  }
  int len = hexString.length();
  char[] output = new char[len+len/2];
  int i=0;
  int j=0;
  while(i<len){
      output[j++]='%';
      output[j++]=hexString.charAt(i++);
      output[j++]=hexString.charAt(i++);
  }
  return new String(output);
}

ستحتاج إلى تحويل وحدات البايت الأولية إلى أحرف سداسية عشرية أو أي ترميز مناسب لعنوان URL تستخدمه.من الممكن استخدام ترميز Base32 أو Base64، لكن الأحرف السداسية العشرية المستقيمة هي الأكثر شيوعًا.ليس هناك حاجة إلى URLEncoder لهذه السلسلة، لأنه لا ينبغي أن يحتوي على أي أحرف تتطلب ترميز URL إلى تنسيق %NN.

سيقوم ما يلي بتحويل بايتات التجزئة (SHA-1، MD5SUM، إلخ) إلى سلسلة سداسية عشرية:

/** Lookup table: character for a half-byte */
    static final char[] CHAR_FOR_BYTE = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
         /** Encode byte data as a hex string... hex chars are UPPERCASE*/
         public static String encode(byte[] data){
             if(data == null || data.length==0){
                 return "";
             }
             char[] store = new char[data.length*2];
             for(int i=0; i<data.length; i++){
                 final int val = (data[i]&0xFF);
                 final int charLoc=i<<1;
                 store[charLoc]=CHAR_FOR_BYTE[val>>>4];
                 store[charLoc+1]=CHAR_FOR_BYTE[val&0x0F];
             }
             return new String(store);
         }

تم تحسين هذا الرمز وسرعته إلى حد ما، وأنا أستخدمه لتشفير البايت SHA-1 الخاص بي.لاحظ أنك قد تحتاج إلى تحويل الأحرف الكبيرة إلى أحرف صغيرة باستخدام أسلوب String.toLowerCase()، اعتمادًا على النموذج الذي يقبله الخادم.

نصائح أخرى

وهذا يعتمد على ما يتوقعه المستفيد من طلبك. أتصور أنه يمكن أن يكون تمثيل عشري من وحدات البايت في التجزئة الخاصة بك. سلسلة ربما لا يكون أفضل فكرة، لأن مجموعة التجزئة من المرجح أن تحتوي على قيم الشخصية غير القابلة للطباعة.

وكنت تكرار عبر مجموعة واستخدام Integer.toHexValue () لتحويل بايت عرافة.

SHA1 بتنسيق سداسي عشري [0-9a-f]، ولن تكون هناك حاجة إلى تشفيره عبر URL.

استخدم أباتشي العموم-ترميز للحصول على جميع الاحتياجات ترميز / فك التشفير الخاص بك (باستثناء ASN 0.1، وهو ألم في المؤخرة)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top