สำหรับคนที่เรียนจบมาทางคอมพิวเตอร์นั้น ถ้าใครเคยเรียนวิชา Assembly มา คงจะจำหลักการพื้นฐานได้อย่างหนึ่ง นั่นก็คือ …
Low Data Low Address
High Data High Address
ความหมายง่าย ๆ ถ้าแปลเป็นไทยก็ ข้อมูลต่ำ ๆ ก็ต้องอยู่ที่ต่ำ ๆ ส่วนข้อมูลสูง ๆ ก็ต้องอยู่ที่สูง ๆ 😛 แปลได้กวนประสาทจริง ๆ อ่ะเอาจริง ๆ ดีกว่า ยกตัวอย่างแล้วจะเข้าใจ
ตัวอย่างเช่นถ้าตัวเลขที่เราจะเก็บลงในหน่วยความจำหลัก มันมีค่าเท่ากับ 1,000,000 ดังนั้นถ้าเราเอาตัวเลขดังกล่าวซึ่งเป็นเลขฐานสิบ มาแปลงให้กลายเป็นเลขฐานสิบหกก็จะได้เป็น 0F4240 (กดเครื่องคิดเลขเลยถ้าไม่เชื่อ :-P)
แต่เนื่องจากตามหลักการแล้วคอมพิวเตอร์จะเก็บข้อมูลตามนิยาม Low Low High High อะไรที่ว่า ดังนั้นมันก็จะเอาตัวเลขดังกล่าวมาเก็บเป็น … 40420F โดย
- Address แรก เก็บค่า 1 ไบต์ ซึ่งก็คือ 40
- Address สอง เก็บค่า 1 ไบต์ ซึ่งก็คือ 42
- Address สาม เก็บค่า 1 ไบต์ ซึ่งก็คือ 0F
งั้นพักเรื่องนี้ไว้ก่อน เพื่อเป็นพื้นฐานสำหรับปูทางเพื่อโม้เรื่อง CRC ที่ผมให้ความฉงนสนเท่ห์กัน
ในทางคอมพิวเตอร์เครือข่ายนั้น การส่งข้อมูลไปมาระหว่างคอมพิวเตอร์ จุดสำคัญอยู่ที่ความถูกต้องของข้อมูล และความรวดเร็วในการรับส่งข้อมูล แล้วก็อย่างที่เราก็รู้ ๆ กันว่า การส่งข้อมูลระหว่างคอมพิวเตอร์นั้น จะไม่ส่งพรวดเดียวจบไปเลย แต่จะรับส่งกันเป็นจังหวะ อีกทั้งยังแบ่งซอยข้อมูลออกเป็นท่อน ๆ เพื่อส่งหากันอีกด้วย
ดังนั้นเพื่อให้คอมพิวเตอร์ฟากรับทราบว่า ท่อนข้อมูลแต่ล่ะท่อนที่ตนเองรับมา มันถูกต้องหรือไม่นั้น คอมพิวเตอร์ฟากส่งจึงจำเป็นต้องแปะอะไรซักอย่างนึงไปพร้อมกับท่อนข้อมูล เพื่อให้สามารถใช้ตรวจสอบได้ว่าท่อนข้อมูลที่ส่งให้นั้น มันไม่ได้ผิด มันถูกต้อง ซึงส่วนใหญ่แล้วก็จะแปะไปที่ท้ายท่อนข้อมูลนั่นแหล่ะ สะดวกดี
อัลกอริทึมเพื่อใช้ตรวจสอบท่อนข้อมูล มีตั้งไม่รู้กี่สิบแบบ แต่ที่ผมจะโม้คือ CRC โดยขอเน้นที่ CRC32 ก็แล้วกัน!!!
ที่ผมจะโม้ก็เพราะว่าวิธีในการตรวจสอบท่อนข้อมูลของ CRC32 มันค่อนข้างขัดแย้งกับกฎ Low Data Low Address High Data High Address น่ะ ยกตัวอย่างงี้ดีกว่า

ผมกำลังสมมติว่า ผมจะส่งคำว่า “LOVE” จากคอมพิวเตอร์ของผม ไปยังคอมพิวเตอร์อีกเครื่องนึง แต่เนื่องจากผมกลัวว่าคอมพิวเตอร์ฟากรับ มันจะไม่แน่ใจว่าผมส่งอะไรไปให้ ผมเลยจะเอาคำว่า “LOVE” มาคำนวณด้วยฟังค์ชัน CRC32 ซึ่งสามารถเรียกใช้ได้จาก Library มาตรฐานทั่ว ๆ ไป รู้สึกว่าแม้แต่ใน PHP ก็มีฟังค์ชัน CRC32 เหมือนกัน
ฟังค์ชัน CRC32 เมื่อรับเอาข้อความ “LOVE” ซึ่งก็คือข้อมูลเลขฐานสิบหกจำนวน 4 ไบต์คือ 4C, 4F, 56 และ 45 เข้าไปคำนวณโช๊ะ ๆ แล้ว ก็ย่อมต้องปล่อยผลลัพท์ออกมาเป็นตัวเลข 4 ไบต์ถูกแมะ เพราะมันเป็น 32 บิต ซึ่งค่าที่ได้ก็คือ

กติกา CRC32 เป็นอะไรที่ผมชอบมากมันง่ายดี ถ้าจะโม้ให้ง่าย ๆ ก็คือ เราจะเอาข้อมูลของเรามาหา CRC32 จากนั้นก็เอาค่าผลลัพท์ที่ได้จาก CRC32 ซึ่งมีขนาด 4 ไบต์ มาแปะต่อท้ายข้อมูลของเรา แล้วส่งไปยังคอมพิวเตอร์ฟากรับ คอมพิวเตอร์ฟากรับก็เอาข้อมูลที่เราส่งให้ มาคำนวณ CRC32 อีกที ถ้าผลลัพท์ที่ได้เป็นเลขเฉพาะซักตัวนึง ก็แสดงว่ามันข้อมูลมันถูกต้อง ซึ่งเลขเฉพาะที่ว่านั้น ถ้ามันไม่มีค่าเป็น 0 ก็จะมีค่าเท่ากับ 7FFFFFFF ซึ่งเป็นเลขฐานสิบหก
ทีนี้โดยกติกา Low Data Low Address High Data High Address ค่า 6117BDA9 ก็ควรถูกเก็บอยู่ในหน่วยความหลักเป็น A9BD1761 สินะ งั้นเวลาเอาไปแปะกับท่อนข้อมูล “LOVE” เพื่อส่งให้กับคอมพิวเตอร์ฟากรับก็ควรจะเป็นดังภาพข้างล่าง

จะเห็นว่าหลังจากเอาข้อความซึ่งแปะ CRC32 มาคำนวณ CRC32 อีกครั้ง ผลลัพท์มันกลับไม่ถูก ที่ถูกมันต้องมีค่าเป็น 7FFFFFFF งั้นลองเปลี่ยนใหม่นะ เปลี่ยนแบบฝืนกติกาไปเลยคือเป็น Low Data High Address High Data Low Address ซึ่งก็หมายความว่า เราจะเอาค่า 6117BDA9 แปะเข้าไปท้ายท่อนข้อมูลเลย แล้วคำนวณ CRC32 ใหม่ ซึ่งก็จะได้ผลลัพท์เหมือนภาพข้างล่าง

คราวนี้คำตอบมันถูก มันได้ผลลัพท์เป็น 7FFFFFFF
ผมรู้สึกนะว่ามันเป็นอะไรที่ฉงนสนเท่ห์มาก ๆ เลยล่ะ แต่ผมเองก็ขี้เกียจไปหาคำตอบเหมือนกัน ว่าทำไม CRC32 มันถึงได้มีรูปแบบในการคำนวณ ที่ฝืนต่อหลักการวางข้อมูลในหน่วยความจำเช่นนี้
จากการพิสูจน์เรื่องนี้ทำให้ผมรู้อย่างหนึ่งว่า ทฤษฎีทางคอมพิวเตอร์ที่มีการประกาศใช้นั้น บางครั้งโดยทางปฏิบัติแล้ว มันก็มีอะไรนิดหน่อยที่ไม่ได้ถูกบอกไว้ในหลักทฤษฎีเหมือนกัน อย่างเรื่อง CRC32 นี่ยังไง ไม่เห็นมันจะบอกไว้เลยว่าโดยทางปฏิบัติแล้ว เราต้องแปะ CRC32 ไว้ท้ายท่อนข้อมูล ด้วยรูปแบบ Low Data High Address High Data Low Address ถึงจะได้ผลลัพท์ที่ถูกต้อง
การสร้างซอฟต์แวร์ เป็นศาสตร์ที่ต้องลงมือปฏิบัติครับ เจนจัดเพียงแค่ทฤษฎีอย่างเดียวมันไม่ถูกต้องหรอก เหอ ๆ 😛
[tags]CRC,CRC32,การสร้างซอฟต์แวร์,คอมพิวเตอร์,ซอฟต์แวร์[/tags]
ไช่ big endian กับ little endien ป่าวอะครับ หรือคนละเรื่องหว่า
เรื่องเดียวกันครับ platform independent ครับอันนี้CRC คนสมัยนี้น่าจะเรียกว่า checksum ครับ
ผมเอาศัพท์ที่คุณ nat3 บอกมา ไปค้นใน wikipedia ดูแล้วนะ ตอนนี้ผมได้คำตอบแล้วล่ะ ในที่สุดก็เข้าใจซะที ว่าทำไมมันถึงเรียงไบต์กลับไปกลับมาแบบนี้