Redis之小端转大端

来源:互联网 发布:java算法技术手册 编辑:程序博客网 时间:2024/05/16 07:30

redis的Endianconv.c文件主要服务于inset集合升级,

其实看以看出它是做了个转换,将小端转成大端的方法

#include <stdint.h>/* Toggle the 16 bit unsigned integer pointed by *p from little endian to * big endian */void memrev16(void *p) {    unsigned char *x = p, t;    t = x[0];    x[0] = x[1];    x[1] = t;}/* Toggle the 32 bit unsigned integer pointed by *p from little endian to * big endian */void memrev32(void *p) {    unsigned char *x = p, t;    t = x[0];    x[0] = x[3];    x[3] = t;    t = x[1];    x[1] = x[2];    x[2] = t;}/* Toggle the 64 bit unsigned integer pointed by *p from little endian to * big endian */void memrev64(void *p) {    unsigned char *x = p, t;    t = x[0];    x[0] = x[7];    x[7] = t;    t = x[1];    x[1] = x[6];    x[6] = t;    t = x[2];    x[2] = x[5];    x[5] = t;    t = x[3];    x[3] = x[4];    x[4] = t;}uint16_t intrev16(uint16_t v) {    memrev16(&v);    return v;}uint32_t intrev32(uint32_t v) {    memrev32(&v);    return v;}uint64_t intrev64(uint64_t v) {    memrev64(&v);    return v;}#ifdef TESTMAIN#include <stdio.h>int main(void) {    char buf[32];    sprintf(buf,"ciaoroma");    memrev16(buf);    printf("%s\n", buf);    sprintf(buf,"ciaoroma");    memrev32(buf);    printf("%s\n", buf);    sprintf(buf,"ciaoroma");    memrev64(buf);    printf("%s\n", buf);    return 0;}#endif


在网络上传输数据时,由于数据传输的两端可能对应不同的硬件平台,采用的存储字节顺序也可能不一致,因此 TCP/IP 协议规定了在网络上必须采用网络字节顺序(也就是大端模式) 。
通过对大小端的存储原理分析可发现,对于 char 型数据,由于其只占一个字节,所以不存在这个问题,这也是一般情况下把数据缓冲区定义成 char 类型 的原因之一。对于 IP 地址、端口号等非 char 型数据,必须在数据发送到网络上之前将其转换成大端模式,在接收到数据之后再将其转换成符合接收端主机的存储模式。

Linux 系统为大小端模式的转换提供了 4 个函数,输入 man byteorder 命令可得函数原型:

#include <arpa/inet.h>  uint32_t htonl(uint32_t hostlong);  uint16_t htons(uint16_t hostshort);  uint32_t ntohl(uint32_t netlong);  uint16_t ntohs(uint16_t netshort); 

大小端转换方法:

#include<stdlib.h>

#include<stdio.h>

#define Tranverse16(X)                 ((((UINT16)(X) & 0xff00) >> 8) |(((UINT16)(X) & 0x00ff) << 8))
#define Tranverse32(X)                 ((((UInt32)(X) & 0xff000000) >> 24) | /
                                                           (((UInt32)(X) & 0x00ff0000) >> 8) | /
                                                           (((UInt32)(X) & 0x0000ff00) << 8) | /
                                                           (((UInt32)(X) & 0x000000ff) << 24))



0 0
原创粉丝点击