سؤال

أقوم بحساب 16 بتات على بياناتي التي أحتاج إلى إرسالها إلى الخادم حيث يتعين عليه إعادة حساب ومطابقة الفحوصات المقدمة. قيمة الشيكات التي أحصل عليها هي في INT ولكن لديّ بايتان فقط لإرسال القيمة. int إلى short أثناء الاتصال shortToBytes طريقة. هذا يعمل بشكل جيد حتى تكون قيمة الفحص أقل من 32767 بعد ذلك أحصل على قيم سلبية.

الشيء هو أن Java ليس لديه بدايات غير موقعة ، لذلك أنا غير قادر على إرسال قيم أكبر من أقصى قيمة التوقيع short مسموح.

كيف يمكنني القيام بذلك ، وتحويل int إلى القصور وإرسال الشبكة دون القلق بشأن الاقتطاع وتوقيعه وغير موقّع.

أيضا على كل من الجانب لدي برنامج Java تشغيل.

   private byte[] shortToBytes(short sh) {
        byte[] baValue = new byte[2];
        ByteBuffer buf = ByteBuffer.wrap(baValue);
        return buf.putShort(sh).array();
    }

    private short bytesToShort(byte[] buf, int offset) {
        byte[] baValue = new byte[2];
        System.arraycopy(buf, offset, baValue, 0, 2);
        return ByteBuffer.wrap(baValue).getShort();
    }
هل كانت مفيدة؟

المحلول

لا تزال تحصل على نفس قيمة البت مثل الخادم. لذلك ، لرؤية القيمة العددية الصحيحة استبدال ByteBuffer.wrap(baValue).getShort() إلى ByteBuffer.wrap(baValue).getInt(). هذا يجب أن يمنحك نفس القيمة العددية مثل الخادم.

نصائح أخرى

char هو نوع 16 بت غير موقعة. في الواقع ، إنه النوع الوحيد غير الموقّع في جافا. يمكنك استخدامه لحساب الفحص ثم استخدام أ ByteBuffer للحصول على البايتات أو ببساطة استخدام bitwise والتحول الصحيح للحصول على البايتات.

نضع في اعتبارنا أن byteيتم توقيع S.

أولا ، جافا int, short و byte يتم توقيع جميع الأنواع غير موقعة. ثانياً ، عندما تلقي جافا int إلى short, ، وما إلى ذلك سوف تحصل على اقتطاع صامت.

ما إذا كان هذا يهم يعتمد على طبيعة خوارزمية الفحص. إذا كان هذا مبلغًا بسيطًا ، أو خوارزمية صغيرة ، فهناك فرصة جيدة لأن تكون الخوارزمية على ما يرام عند تنفيذها باستخدام أعداد صحيحة موقعة من Java. على سبيل المثال ، يمكن أن تكون عمليات الفحص "السلبية" 16bit صحيحة عند تفسيرها بشيء يتوقع قيمًا غير موقعة.

من ناحية أخرى ، فإن الدلالي للضرب والانقسام هي أن النكهات الموقعة وغير الموقعة يجب التعامل معها بشكل منفصل. (على الأقل ، هذا ما استنتجه من النهج غير العلمي المتمثل في النظر إلى مجموعة تعليمات X86 ... التي لديها تعليمات منفصلة للضرب والتقسيم غير الموقّع.)

تعديل أنا أفهم أنك تحسب CRC-16. نظرًا لأن ذلك يمكن حسابه عن طريق التحول والكرن ، يجب ألا يكون هناك أي مخاوف بشأن الأرقام الموقعة مقابل الأرقام غير الموقعة أثناء الحساب.

باختصار ، ليس لديك أي شيء يدعو للقلق.

عندما تقول أنك تحصل على قيم سلبية ، أفترض أنك تقصد عندما تقرأ قيمة 16 بت وتحولها إلى عدد صحيح. والسبب في ذلك هو أن تمديد الإشارة يتسبب في أهم بت (وهو 1) ليتم تكراره عند short يتم توسيعه إلى int. الحل البسيط هو bitwise و integer المعاد بناؤه مع 0xFFFF, ، مما يضمن أن أقل 16 بت أقل من 16 بت هي غير صفرية.

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