Chinaunix首页 | 论坛 | 博客
  • 博客访问: 31075
  • 博文数量: 8
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 110
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-29 17:06
文章分类

全部博文(8)

文章存档

2011年(1)

2008年(7)

我的朋友

分类: 项目管理

2008-03-22 13:39:42

最近应产线的要求,需要我们将meid转换成为pesn来使用。
首先,我们来看下meid,这个东西就是以前我们所说的32bit的ESN的扩展版,因为手机越来越多,32bit的ESN已经不能满足需求了,这就出来了一个meid,meid为56bit,我们可以通过sha1算法将meid转换成为pesn.其中pesn也是32bit,成为伪esn。
总共给过来大概有20000万多个meid,需要我们转换成为pesn,其中涉及到了C的memory和file。实现如下:
#include
#include "memory.h"
using namespace std;

typedef  unsigned char     byte;         /* Unsigned 8  bit value type. */
typedef  unsigned short    word;         /* Unsinged 16 bit value type. */
typedef  unsigned long     dword;        /* Unsigned 32 bit value type. */
typedef  unsigned long    qword[2];
/* ------------------------------------------------------------ */
/* Constants and definitions for SHA-1                          */
/* ------------------------------------------------------------ */
typedef union
{
  unsigned long l[16];
  unsigned char c[64];
} CHAR64LONG16;
/* Optimizations */
unsigned long rol30( unsigned long value)
{
  return (value << 30) | ((value >> 2) & 0x3fffffff);
}
unsigned long rol24( unsigned long value)
{
  return (value << 24) | ((value >> 8) & 0x00ffffff);
}
unsigned long rol8( unsigned long value)
{
  return (value << 8) | ((value >> 24) & 0x000000ff);
}
unsigned long rol5( unsigned long value)
{
  return (value << 5) | ((value >> 27) & 0x0000001f);
}
unsigned long rol1( unsigned long value)
{
  return (value << 1) | ((value >> 31) & 0x00000001);
}
/* blk0() and blk() perform the initial expand */
//#if defined(__BIG_ENDIAN)
//#define blk0(block, i)      (block->l[i])
//#else
#define blk0(block, i)      (block->l[i]        = (rol24(block->l[i]) & 0xff00ff00UL) | (rol8(block->l[i]) & 0x00ff00ffUL))
//#endif
#define blk(block, i)       (block->l[i & 0x0f] = rol1(block->l[(i + 13) & 0x0f] ^ block->l[(i +  8) & 0x0f] ^ block->l[(i +  2) & 0x0f] ^ block->l[(i +  0) & 0x0f]))
/* R0, R1, R2, R3, R4 are the different operations used in SHA1 */
#define R0(block, work, v, w, x, y, z, i) \
    (work[z] += ((work[w]&(work[x]^work[y]))^work[y])           + blk0(block, i) + 0x5a827999UL + rol5(work[v]), work[w] = rol30(work[w]))
#define R1(block, work, v, w, x, y, z, i) \
    (work[z] += ((work[w]&(work[x]^work[y]))^work[y])           + blk(block, i)  + 0x5a827999UL + rol5(work[v]), work[w] = rol30(work[w]))
#define R2(block, work, v, w, x, y, z, i) \
    (work[z] += (work[w]^work[x]^work[y])                       + blk(block, i)  + 0x6ed9eba1UL + rol5(work[v]), work[w] = rol30(work[w]))
#define R3(block, work, v, w, x, y, z, i) \
    (work[z] += (((work[w]|work[x])&work[y])|(work[w]&work[x])) + blk(block, i)  + 0x8f1bbcdcUL + rol5(work[v]), work[w] = rol30(work[w]))
#define R4(block, work, v, w, x, y, z, i) \
    (work[z] += (work[w]^work[x]^work[y])                       + blk(block, i)  + 0xca62c1d6UL + rol5(work[v]), work[w] = rol30(work[w]))
/* end of duplicated defines */

#define QW_BYTE(val,idx)  \
(                         \
  ( (byte*)(val) )[ idx ] \
)
#define  MCC_PESN_PREFIX       0x80000000UL     /* Pseudo-ESN Prefix */
#define  MCC_PESN_PREFIX_MASK  0xFF000000UL     /* Pseudo-ESN Prefix mask */
 
void mcc_meid_create_sha1_digest
(
  qword meid,   /* Mobile Equipment Identifier */
  unsigned long * pmeidhash  /* SHA-1 digest */
);
void mcc_sechsharm_sha1_transform
(
  unsigned long*  iv,
  unsigned char*  buf
);
/*===========================================================================
FUNCTION MCC_MEID_CREATE_SHA1_DIGEST
DESCRIPTION
  This function computes the msg digest (160 bits) using the SHA-1 algorithm.
DEPENDENCIES
RETURN VALUE
    TRUE - Success
    FALSE - Fail
SIDE EFFECTS
===========================================================================*/
void mcc_meid_create_sha1_digest
(
  qword meid,   /* Mobile Equipment Identifier */
  unsigned long * pmeidhash  /* SHA-1 digest */
)
{
  unsigned char      m[64];
  int i;             /* loop varaible */
  /* Pad the MEID field to form a 512 bit block,
   * the padding shall be a 1 followed by all '0's,
   * the last 64 bits shall be the binary representation
   * of the message length, in this case, 56.
   */
  for (i=0; i< 64; i++)
  {
    m[i] = 0;
  }
  m[0] = QW_BYTE(meid, 6);
  m[1] = QW_BYTE(meid, 5);
  m[2] = QW_BYTE(meid, 4);
  m[3] = QW_BYTE(meid, 3);
  m[4] = QW_BYTE(meid, 2);
  m[5] = QW_BYTE(meid, 1);
  m[6] = QW_BYTE(meid, 0);
  m[7] = 0x80;   
  m[60] = 0;
  m[61] = 0;
  m[62] = 0;
  m[63] = 0x38;
  /* SHA1 initialization constants */
  pmeidhash[0] = 0x67452301UL;
  pmeidhash[1] = 0xefcdab89UL;
  pmeidhash[2] = 0x98badcfeUL;
  pmeidhash[3] = 0x10325476UL;
  pmeidhash[4] = 0xc3d2e1f0UL;
  mcc_sechsharm_sha1_transform(pmeidhash, m );
}
/*===========================================================================
FUNCTION MCC_SECHSHARM_SHA1_TRANSFORM
DESCRIPTION
  This function performs the SHA-1 algorithm.
DEPENDENCIES
RETURN VALUE
    None
SIDE EFFECTS
===========================================================================*/
void mcc_sechsharm_sha1_transform
(
  unsigned long*  iv,
  unsigned char*  buf
)
{
  unsigned long bufi[16];                             /* internal buffer */
  unsigned long work[5];                      /* internal work registers */
  CHAR64LONG16*  block = (CHAR64LONG16*) bufi;
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /* Copy operating buffer to buf */
  memcpy( bufi, buf, sizeof( bufi ) );
  /* Copy context->iv[] to working vars */
  work[0] = iv[0];                 /* a */
  work[1] = iv[1];                 /* b */
  work[2] = iv[2];                 /* c */
  work[3] = iv[3];                 /* d */
  work[4] = iv[4];                 /* e */
  /* 4 rounds of 20 operations each. Loop unrolled */
  /* Round 1 */
  R0( block, work, 0, 1, 2, 3, 4,  0 );
  R0( block, work, 4, 0, 1, 2, 3,  1 );
  R0( block, work, 3, 4, 0, 1, 2,  2 );
  R0( block, work, 2, 3, 4, 0, 1,  3 );
  R0( block, work, 1, 2, 3, 4, 0,  4 );
  R0( block, work, 0, 1, 2, 3, 4,  5 );
  R0( block, work, 4, 0, 1, 2, 3,  6 );
  R0( block, work, 3, 4, 0, 1, 2,  7 );
  R0( block, work, 2, 3, 4, 0, 1,  8 );
  R0( block, work, 1, 2, 3, 4, 0,  9 );
  R0( block, work, 0, 1, 2, 3, 4, 10 );
  R0( block, work, 4, 0, 1, 2, 3, 11 );
  R0( block, work, 3, 4, 0, 1, 2, 12 );
  R0( block, work, 2, 3, 4, 0, 1, 13 );
  R0( block, work, 1, 2, 3, 4, 0, 14 );
  R0( block, work, 0, 1, 2, 3, 4, 15 );
  R1( block, work, 4, 0, 1, 2, 3, 16 );
  R1( block, work, 3, 4, 0, 1, 2, 17 );
  R1( block, work, 2, 3, 4, 0, 1, 18 );
  R1( block, work, 1, 2, 3, 4, 0, 19 );
  /* Round 2 */
  R2( block, work, 0, 1, 2, 3, 4, 20 );
  R2( block, work, 4, 0, 1, 2, 3, 21 );
  R2( block, work, 3, 4, 0, 1, 2, 22 );
  R2( block, work, 2, 3, 4, 0, 1, 23 );
  R2( block, work, 1, 2, 3, 4, 0, 24 );
  R2( block, work, 0, 1, 2, 3, 4, 25 );
  R2( block, work, 4, 0, 1, 2, 3, 26 );
  R2( block, work, 3, 4, 0, 1, 2, 27 );
  R2( block, work, 2, 3, 4, 0, 1, 28 );
  R2( block, work, 1, 2, 3, 4, 0, 29 );
  R2( block, work, 0, 1, 2, 3, 4, 30 );
  R2( block, work, 4, 0, 1, 2, 3, 31 );
  R2( block, work, 3, 4, 0, 1, 2, 32 );
  R2( block, work, 2, 3, 4, 0, 1, 33 );
  R2( block, work, 1, 2, 3, 4, 0, 34 );
  R2( block, work, 0, 1, 2, 3, 4, 35 );
  R2( block, work, 4, 0, 1, 2, 3, 36 );
  R2( block, work, 3, 4, 0, 1, 2, 37 );
  R2( block, work, 2, 3, 4, 0, 1, 38 );
  R2( block, work, 1, 2, 3, 4, 0, 39 );
  /* Round 3 */
  R3( block, work, 0, 1, 2, 3, 4, 40 );
  R3( block, work, 4, 0, 1, 2, 3, 41 );
  R3( block, work, 3, 4, 0, 1, 2, 42 );
  R3( block, work, 2, 3, 4, 0, 1, 43 );
  R3( block, work, 1, 2, 3, 4, 0, 44 );
  R3( block, work, 0, 1, 2, 3, 4, 45 );
  R3( block, work, 4, 0, 1, 2, 3, 46 );
  R3( block, work, 3, 4, 0, 1, 2, 47 );
  R3( block, work, 2, 3, 4, 0, 1, 48 );
  R3( block, work, 1, 2, 3, 4, 0, 49 );
  R3( block, work, 0, 1, 2, 3, 4, 50 );
  R3( block, work, 4, 0, 1, 2, 3, 51 );
  R3( block, work, 3, 4, 0, 1, 2, 52 );
  R3( block, work, 2, 3, 4, 0, 1, 53 );
  R3( block, work, 1, 2, 3, 4, 0, 54 );
  R3( block, work, 0, 1, 2, 3, 4, 55 );
  R3( block, work, 4, 0, 1, 2, 3, 56 );
  R3( block, work, 3, 4, 0, 1, 2, 57 );
  R3( block, work, 2, 3, 4, 0, 1, 58 );
  R3( block, work, 1, 2, 3, 4, 0, 59 ); 
  /* Round 4 */
  R4( block, work, 0, 1, 2, 3, 4, 60 );
  R4( block, work, 4, 0, 1, 2, 3, 61 );
  R4( block, work, 3, 4, 0, 1, 2, 62 );
  R4( block, work, 2, 3, 4, 0, 1, 63 );
  R4( block, work, 1, 2, 3, 4, 0, 64 );
  R4( block, work, 0, 1, 2, 3, 4, 65 );
  R4( block, work, 4, 0, 1, 2, 3, 66 );
  R4( block, work, 3, 4, 0, 1, 2, 67 );
  R4( block, work, 2, 3, 4, 0, 1, 68 );
  R4( block, work, 1, 2, 3, 4, 0, 69 );
  R4( block, work, 0, 1, 2, 3, 4, 70 );
  R4( block, work, 4, 0, 1, 2, 3, 71 );
  R4( block, work, 3, 4, 0, 1, 2, 72 );
  R4( block, work, 2, 3, 4, 0, 1, 73 );
  R4( block, work, 1, 2, 3, 4, 0, 74 );
  R4( block, work, 0, 1, 2, 3, 4, 75 );
  R4( block, work, 4, 0, 1, 2, 3, 76 );
  R4( block, work, 3, 4, 0, 1, 2, 77 );
  R4( block, work, 2, 3, 4, 0, 1, 78 );  
  R4( block, work, 1, 2, 3, 4, 0, 79 );
  /* Add the working vars back into context.iv[] */
  iv[0] += work[0];
  iv[1] += work[1];
  iv[2] += work[2];
  iv[3] += work[3];
  iv[4] += work[4];
} /* sechsharm_sha1_transform() */
 
int main()
{
 dword     pesn = 0x0UL;     /* pseudo-ESN */
 unsigned long meidhash[5];  /* MEID SHA-1 digest */
 unsigned long meid[2];
 unsigned int j;
 char str[15];
 byte a[16];
 int i;
 FILE* fpin;
 FILE* fpout;
 fpin = fopen("a.txt","rt");
 fpout = fopen("b.txt","at");
 for(j=0; j<28801; j++)
 {
  fseek(fpin, j*17*sizeof(char), 0);
  memset(str, 0, 15*sizeof(char));
  fgets(str, 15, fpin);
  memset(a, 0, 16*sizeof(byte));
  for(i=0; i<14; i++)
  {
   if(str[i] <= 57)
    a[i + 2] = str[i] - 48;
   else if(str[i] >= 97 && str[i] <= 102)
    a[i + 2] = str[i] -97 + 10;
   else if(str[i] >= 65 && str[i] <= 70)
    a[i + 2] = str[i] - 65 + 10;
  }
 
  meid[0] = (dword)a[8]<<28 | (dword)a[9]<<24 | (dword)a[10]<<20 | (dword)a[11]<<16 | (dword)a[12]<<12 | (dword)a[13]<<8 | (dword)a[14]<<4 | (dword)a[15];
  meid[1] = (dword)a[0]<<28 | (dword)a[1]<<24 | (dword)a[2]<<20 | (dword)a[3]<<16 | (dword)a[4]<<12 | (dword)a[5]<<8 | (dword)a[6]<<4 | (dword)a[7];
  /*
   meid[0] = 0x652983B;
   meid[1] = 0xa10000;
  */
  mcc_meid_create_sha1_digest(meid, meidhash);
  /* SHA-1 digest(hash) was successfully created */
  /* the p-ESN is in the lowest 24 bits of meidhash[4] */
  pesn = (meidhash[4] & ~MCC_PESN_PREFIX_MASK) | (MCC_PESN_PREFIX);
  fprintf(fpout, "%x\n", pesn);
 }
 fclose(fpin);
 fclose(fpout);
 return 0;
}
 
我们定义了2个文件,一个为输入文件,一个为输出文件,输入文件里面保存的是需要转换的meid,输出文件中保存转换完后的pesn。sha1的算法我们就不具体的说了,主要说下如何实现读写文件。
 
大体的思路应该是这样的:首先,我们从input.txt中读入我们需要的meid,并以char的形式保存到一个数组中,这里我们定义的数组里面保存14个元素,因为保存的是16进制,总共56位。接下来是将数组元素转换成为对应的值,这里有一点需要注意,meid里面的字符串有ABCDEF和abcdef以及0-9之分,而16进制的A和a所代表的值都是一样的,在转换的时候需要考虑到这点。将数组元素由char转换成为8位无符号整数,接下来要做的是将每个数组元素中的低4位取出来放到事先定义好的unsigned long的数组中,作为一个值,这个值就是我们所需要转换的meid的一部分。完成meid数组的初始化后,我们就能利用sha1算法来求pesn了,求出的pesn是一个整数值,我们需要使用fprintf()按照16进制的格式来输出。
 
注意:
1.fseek函数的使用:我们用它来改变文件指针的位置,由于我们是从txt文件中读值,而不是二进制文件,因此我们需要注意将换行符或者其他与meid无关的符号所代表的二进制去掉,也就是说在我们从input.txt中读取meid的时候,要注意meid间的符号不能一起读到数组里面来,而且在改变文件指针位置的时候,要把符号位所占的字节数加上,这也就是上面为什么是17而不是15了,因为在meid间有2个字节的间隔。
 
2.从char转换为byte,这里我们采用的是一种比较老的办法,将char中的每个元素减掉字符'0'的ASCII值48,当然这只是针对十进制0-9来说的,由于我们的input.txt里面的meid都是十六进制,还存在ABCDEF,abcdef大小写的区分,这里的a应该表示的是10,于是我们在转换的时候,便需要进行判断是0-9还是大写字母,还是小写字母,分别减掉字符'0','A','a'的ASCII值,这样就得出了我们所需要的byte数组。
 
3.从byte数组向meid的转换,byte数组中总共有16个元素,而且数组中的每个元素均不大于0x0F,我们需要将byte数组中的前8个元素转换成为unsigned long的meid数组的第二个元素,需要将byte数组中的后8个元素转换成为meid数组中的第一个元素,现在我们需要考虑一下,8个byte类型的数组元素总共是占了64位,而meid的一个元素只是占了32位,我们需要将byte类型数组中的每个元素的低4位取出来,然后放到对应的meid元素里面。这里采用了移位或的办法。
阅读(3723) | 评论(4) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-07-20 17:25:12

能提供输入文件的sample么?

chinaunix网友2009-04-30 13:16:54

hehe,QUALCOMM code.

chinaunix网友2008-11-28 00:27:06

可以将EsN转换为meid吗?

chinaunix网友2008-11-28 00:26:41

可以将ECN转换为meid吗?