C/C++ MD5算法的实现代码

在逆向程序的时候,经常会碰到加密的算法的问题,前面分析UC的逆向工程师的面试题2的时候,发现使用了MD5的加密算法(MD5算法是自己实现的,不是使用的算法库函数)。尤其是在逆向分析网络协议的时候,一般的程序使用的加密算法都是使用的库函数提供的算法,有些程序使用的算法是自己实现的;相对来说使用函数库提供的加密函数的算法相对来说比较好识别,因为有算法常见函数在;但是如果不是使用的函数库提供的加密的函数而是自己去实现某些算法话,识别起来有一定的难度,这就需要你对函数的加密原理以及流程还算法的特征比较熟悉才能很快识别出来。下面就将网上有关MD5算法一些知识整理一下,方面自己查阅。

md5简介

消息摘要算法第五版(英语:Message-Digest Algorithm 5,缩写为MD5),是当前计算机领域用于确保信息传输完整一致而广泛使用的散列算法之一(又译哈希算法、摘要算法等),主流编程语言普遍已有MD5的实现。将数据 (如一段文字)运算变为另一固定长度值,是散列算法的基础原理,MD5的前身有MD2、MD3和MD4。MD5由MD4、MD3、MD2改进而来,主要增强算法复杂度和不可逆性。目前,MD5算法因其普遍、稳定、快速的特点,仍广泛应用于普通 数据的错误检查领域。例如在一些BitTorrent下载中,软件将通过计算MD5检验下载到的文件片段的完整性。MD5已经广泛使用在为文件传输提供一定的可靠性方面。例如,服务器预先提供一个MD5校验和,用户下载完文件以后, 用MD5算法计算下载文件的MD5校验和,然后通过检查这两个校验和是否一致,就能判断下载的文件是否出错。MD5是输入不定长度信息,输出固定长度128-bits的算法。经过程序流程,生成四个32位数据,最后联合起来成为一个 128-bits散列。基本方式为,求余、取余、调整长度、与链接变量进行循环运算。得出结果。

md5算法描述

假设输入信息(input message)的长度为b(bit),我们想要产生它的报文摘要,在此处b为任意的非负整数:b也可能为0,也不一定为8的整数倍,且可能是任意大的长度。设该信息的比特流表示如下: M[0] M[1] M[2] ... M[b-1] 计算此信息的报文摘要需要如下5步:

1.补位

信息计算前先要进行位补位,设补位后信息的长度为LEN(bit),则LEN%512 = 448(bit),即数据扩展至 K * 512 + 448(bit)。即K * 64+56(byte),K为整数。补位操作始终要执行,即使补位前信息的长度对512求余的结果是448。具体补位操作:补一个1,然后补0至满足上述要求。总共最少要补1bit,最多补512bit。

2.尾部加上信息长度

将输入信息的原始长度b(bit)表示成一个64-bit的数字,把它添加到上一步的结果后面(在32位的机器上,这64位将用2个字来表示并且低位在前)。当遇到b大于2^64这种极少的情况时,b的高位被截去,仅使用b的低64位。经过上面两步,数据就被填补成长度为512(bit)的倍数。也就是说,此时的数据长度是16个字(32byte)的整数倍。此时的数据表示为: M[0 ... N-1] 其中的N是16的倍数。

3.初始化缓存区

用一个四个字的缓冲器(A,B,C,D)来计算报文摘要,A,B,C,D分别是32位的寄存器,初始化使用的是十六进制表示的数字,注意低字节在前: word A: 01 23 45 67 word B: 89 ab cd ef word C: fe dc ba 98 word D: 76 54 32 10

4.转换

首先定义4个辅助函数,每个函数的输入是三个32位的字,输出是一个32位的字: F(X,Y,Z) = XY v not(X) Z G(X,Y,Z) = XZ v Y not(Z) H(X,Y,Z) = X xor Y xor Z I(X,Y,Z) = Y xor (X v not(Z))

FF(a,b,c,d,Mj,s,ti)表示 a = b + ((a + F(b,c,d) + Mj + ti) << s)
GG(a,b,c,d,Mj,s,ti)表示 a = b + ((a + G(b,c,d) + Mj + ti) << s)
HH(a,b,c,d,Mj,s,ti)表示 a = b + ((a + H(b,c,d) + Mj + ti) << s)
Ⅱ(a,b,c,d,Mj,s,ti)表示 a = b + ((a + I(b,c,d) + Mj + ti) << s)

这四轮(64步)是:

第一轮

FF(a,b,c,d,M0,7,0xd76aa478) FF(d,a,b,c,M1,12,0xe8c7b756) FF(c,d,a,b,M2,17,0x242070db) FF(b,c,d,a,M3,22,0xc1bdceee) FF(a,b,c,d,M4,7,0xf57c0faf) FF(d,a,b,c,M5,12,0x4787c62a) FF(c,d,a,b,M6,17,0xa8304613) FF(b,c,d,a,M7,22,0xfd469501) FF(a,b,c,d,M8,7,0x698098d8) FF(d,a,b,c,M9,12,0x8b44f7af) FF(c,d,a,b,M10,17,0xffff5bb1) FF(b,c,d,a,M11,22,0x895cd7be) FF(a,b,c,d,M12,7,0x6b901122) FF(d,a,b,c,M13,12,0xfd987193) FF(c,d,a,b,M14,17,0xa679438e) FF(b,c,d,a,M15,22,0x49b40821)

第二轮

GG(a,b,c,d,M1,5,0xf61e2562) GG(d,a,b,c,M6,9,0xc040b340) GG(c,d,a,b,M11,14,0x265e5a51) GG(b,c,d,a,M0,20,0xe9b6c7aa) GG(a,b,c,d,M5,5,0xd62f105d) GG(d,a,b,c,M10,9,0x02441453) GG(c,d,a,b,M15,14,0xd8a1e681) GG(b,c,d,a,M4,20,0xe7d3fbc8) GG(a,b,c,d,M9,5,0x21e1cde6) GG(d,a,b,c,M14,9,0xc33707d6) GG(c,d,a,b,M3,14,0xf4d50d87) GG(b,c,d,a,M8,20,0x455a14ed) GG(a,b,c,d,M13,5,0xa9e3e905) GG(d,a,b,c,M2,9,0xfcefa3f8) GG(c,d,a,b,M7,14,0x676f02d9) GG(b,c,d,a,M12,20,0x8d2a4c8a)

第三轮

HH(a,b,c,d,M5,4,0xfffa3942) HH(d,a,b,c,M8,11,0x8771f681) HH(c,d,a,b,M11,16,0x6d9d6122) HH(b,c,d,a,M14,23,0xfde5380c) HH(a,b,c,d,M1,4,0xa4beea44) HH(d,a,b,c,M4,11,0x4bdecfa9) HH(c,d,a,b,M7,16,0xf6bb4b60) HH(b,c,d,a,M10,23,0xbebfbc70) HH(a,b,c,d,M13,4,0x289b7ec6) HH(d,a,b,c,M0,11,0xeaa127fa) HH(c,d,a,b,M3,16,0xd4ef3085) HH(b,c,d,a,M6,23,0x04881d05) HH(a,b,c,d,M9,4,0xd9d4d039) HH(d,a,b,c,M12,11,0xe6db99e5) HH(c,d,a,b,M15,16,0x1fa27cf8) HH(b,c,d,a,M2,23,0xc4ac5665)

第四轮

Ⅱ(a,b,c,d,M0,6,0xf4292244) Ⅱ(d,a,b,c,M7,10,0x432aff97) Ⅱ(c,d,a,b,M14,15,0xab9423a7) Ⅱ(b,c,d,a,M5,21,0xfc93a039) Ⅱ(a,b,c,d,M12,6,0x655b59c3) Ⅱ(d,a,b,c,M3,10,0x8f0ccc92) Ⅱ(c,d,a,b,M10,15,0xffeff47d) Ⅱ(b,c,d,a,M1,21,0x85845dd1) Ⅱ(a,b,c,d,M8,6,0x6fa87e4f) Ⅱ(d,a,b,c,M15,10,0xfe2ce6e0) Ⅱ(c,d,a,b,M6,15,0xa3014314) Ⅱ(b,c,d,a,M13,21,0x4e0811a1) Ⅱ(a,b,c,d,M4,6,0xf7537e82) Ⅱ(d,a,b,c,M11,10,0xbd3af235) Ⅱ(c,d,a,b,M2,15,0x2ad7d2bb) Ⅱ(b,c,d,a,M9,21,0xeb86d391)

下面是MD5算法的具体的实现

MD5算法的头文件Md5.h:

#ifndef MD5_H
#define MD5_H  

typedef struct
{
  unsigned int count[2];
  unsigned int state[4];
  unsigned char buffer[64];
}MD5_CTX; 

#define F(x,y,z) ((x & y) | (~x & z))
#define G(x,y,z) ((x & z) | (y & ~z))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y ^ (x | ~z))
#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))  

#define FF(a,b,c,d,x,s,ac) { \
a += F(b, c, d) + x + ac; \
a = ROTATE_LEFT(a, s); \
a += b; \
} 

#define GG(a,b,c,d,x,s,ac) { \
  a += G(b, c, d) + x + ac; \
  a = ROTATE_LEFT(a, s); \
  a += b; \
} 

#define HH(a,b,c,d,x,s,ac) { \
  a += H(b, c, d) + x + ac; \
  a = ROTATE_LEFT(a, s); \
  a += b; \
}
#define II(a,b,c,d,x,s,ac) { \
  a += I(b, c, d) + x + ac; \
  a = ROTATE_LEFT(a, s); \
  a += b; \
} 

void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);
void MD5Final(MD5_CTX *context, unsigned char digest[16]);
void MD5Transform(unsigned int state[4], unsigned char block[64]);
void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);
void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len); 

#endif

MD5算法的实现文件Md5.cpp:

unsigned char PADDING[] = {
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 

//在逆向代码的时候,需要关注下面的特征值
void MD5Init(MD5_CTX *context)
{
  context->count[0] = 0;
  context->count[1] = 0;
  context->state[0] = 0x67452301;
  context->state[1] = 0xEFCDAB89;
  context->state[2] = 0x98BADCFE;
  context->state[3] = 0x10325476;
} 

void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen)
{
  unsigned int i = 0, index = 0, partlen = 0;
  index = (context->count[0] >> 3) & 0x3F;
  partlen = 64 - index;
  context->count[0] += inputlen << 3;
  if (context->count[0] < (inputlen << 3))
    context->count[1]++;
  context->count[1] += inputlen >> 29; 

  if (inputlen >= partlen)
  {
    memcpy(&context->buffer[index], input, partlen);
    MD5Transform(context->state, context->buffer);
    for (i = partlen; i + 64 <= inputlen; i += 64)
      MD5Transform(context->state, &input[i]);
    index = 0;
  }
  else
  {
    i = 0;
  }
  memcpy(&context->buffer[index], &input[i], inputlen - i);
} 

void MD5Final(MD5_CTX *context, unsigned char digest[16])
{
  unsigned int index = 0, padlen = 0;
  unsigned char bits[8];
  index = (context->count[0] >> 3) & 0x3F;
  padlen = (index < 56) ? (56 - index) : (120 - index);
  MD5Encode(bits, context->count, 8);
  MD5Update(context, PADDING, padlen);
  MD5Update(context, bits, 8);
  MD5Encode(digest, context->state, 16);
} 

void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len)
{
  unsigned int i = 0, j = 0;
  while (j < len)
  {
    output[j] = input[i] & 0xFF;
    output[j + 1] = (input[i] >> 8) & 0xFF;
    output[j + 2] = (input[i] >> 16) & 0xFF;
    output[j + 3] = (input[i] >> 24) & 0xFF;
    i++;
    j += 4;
  }
} 

void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len)
{
  unsigned int i = 0, j = 0;
  while (j < len)
  {
    output[i] = (input[j]) |
      (input[j + 1] << 8) |
      (input[j + 2] << 16) |
      (input[j + 3] << 24);
    i++;
    j += 4;
  }
} 

void MD5Transform(unsigned int state[4], unsigned char block[64])
{
  unsigned int a = state[0];
  unsigned int b = state[1];
  unsigned int c = state[2];
  unsigned int d = state[3];
  unsigned int x[64]; 

  MD5Decode(x, block, 64);
  FF(a, b, c, d, x[0], 7, 0xd76aa478);
  FF(d, a, b, c, x[1], 12, 0xe8c7b756);
  FF(c, d, a, b, x[2], 17, 0x242070db);
  FF(b, c, d, a, x[3], 22, 0xc1bdceee);
  FF(a, b, c, d, x[4], 7, 0xf57c0faf);
  FF(d, a, b, c, x[5], 12, 0x4787c62a);
  FF(c, d, a, b, x[6], 17, 0xa8304613);
  FF(b, c, d, a, x[7], 22, 0xfd469501);
  FF(a, b, c, d, x[8], 7, 0x698098d8);
  FF(d, a, b, c, x[9], 12, 0x8b44f7af);
  FF(c, d, a, b, x[10], 17, 0xffff5bb1);
  FF(b, c, d, a, x[11], 22, 0x895cd7be);
  FF(a, b, c, d, x[12], 7, 0x6b901122);
  FF(d, a, b, c, x[13], 12, 0xfd987193);
  FF(c, d, a, b, x[14], 17, 0xa679438e);
  FF(b, c, d, a, x[15], 22, 0x49b40821); 

  GG(a, b, c, d, x[1], 5, 0xf61e2562);
  GG(d, a, b, c, x[6], 9, 0xc040b340);
  GG(c, d, a, b, x[11], 14, 0x265e5a51);
  GG(b, c, d, a, x[0], 20, 0xe9b6c7aa);
  GG(a, b, c, d, x[5], 5, 0xd62f105d);
  GG(d, a, b, c, x[10], 9, 0x2441453);
  GG(c, d, a, b, x[15], 14, 0xd8a1e681);
  GG(b, c, d, a, x[4], 20, 0xe7d3fbc8);
  GG(a, b, c, d, x[9], 5, 0x21e1cde6);
  GG(d, a, b, c, x[14], 9, 0xc33707d6);
  GG(c, d, a, b, x[3], 14, 0xf4d50d87);
  GG(b, c, d, a, x[8], 20, 0x455a14ed);
  GG(a, b, c, d, x[13], 5, 0xa9e3e905);
  GG(d, a, b, c, x[2], 9, 0xfcefa3f8);
  GG(c, d, a, b, x[7], 14, 0x676f02d9);
  GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); 

  HH(a, b, c, d, x[5], 4, 0xfffa3942);
  HH(d, a, b, c, x[8], 11, 0x8771f681);
  HH(c, d, a, b, x[11], 16, 0x6d9d6122);
  HH(b, c, d, a, x[14], 23, 0xfde5380c);
  HH(a, b, c, d, x[1], 4, 0xa4beea44);
  HH(d, a, b, c, x[4], 11, 0x4bdecfa9);
  HH(c, d, a, b, x[7], 16, 0xf6bb4b60);
  HH(b, c, d, a, x[10], 23, 0xbebfbc70);
  HH(a, b, c, d, x[13], 4, 0x289b7ec6);
  HH(d, a, b, c, x[0], 11, 0xeaa127fa);
  HH(c, d, a, b, x[3], 16, 0xd4ef3085);
  HH(b, c, d, a, x[6], 23, 0x4881d05);
  HH(a, b, c, d, x[9], 4, 0xd9d4d039);
  HH(d, a, b, c, x[12], 11, 0xe6db99e5);
  HH(c, d, a, b, x[15], 16, 0x1fa27cf8);
  HH(b, c, d, a, x[2], 23, 0xc4ac5665); 

  II(a, b, c, d, x[0], 6, 0xf4292244);
  II(d, a, b, c, x[7], 10, 0x432aff97);
  II(c, d, a, b, x[14], 15, 0xab9423a7);
  II(b, c, d, a, x[5], 21, 0xfc93a039);
  II(a, b, c, d, x[12], 6, 0x655b59c3);
  II(d, a, b, c, x[3], 10, 0x8f0ccc92);
  II(c, d, a, b, x[10], 15, 0xffeff47d);
  II(b, c, d, a, x[1], 21, 0x85845dd1);
  II(a, b, c, d, x[8], 6, 0x6fa87e4f);
  II(d, a, b, c, x[15], 10, 0xfe2ce6e0);
  II(c, d, a, b, x[6], 15, 0xa3014314);
  II(b, c, d, a, x[13], 21, 0x4e0811a1);
  II(a, b, c, d, x[4], 6, 0xf7537e82);
  II(d, a, b, c, x[11], 10, 0xbd3af235);
  II(c, d, a, b, x[2], 15, 0x2ad7d2bb);
  II(b, c, d, a, x[9], 21, 0xeb86d391);
  state[0] += a;
  state[1] += b;
  state[2] += c;
  state[3] += d;
} 

MD5算法的调用测试:

int _tmain(int argc, _TCHAR* argv[])
{ 

  int i;
  unsigned char encrypt[] = "admin";//21232f297a57a5a743894a0e4a801fc3
  unsigned char decrypt[16]; 

  MD5_CTX md5; 

  MD5Init(&md5);
  MD5Update(&md5, encrypt, strlen((char *)encrypt));
  MD5Final(&md5, decrypt); 

  //Md5加密后的32位结果
  printf("加密前:%s\n加密后16位:", encrypt);
  for (i = 4; i<12; i++)
  {
    printf("%02x", decrypt[i]);
  } 

  //Md5加密后的32位结果
  printf("\n加密前:%s\n加密后32位:", encrypt);
  for (i = 0; i<16; i++)
  {
    printf("%02x", decrypt[i]);
  } 

  getchar(); 

  return 0;
}

上面的代码工程的下载地址:Md5Demo201707.zip

破解MD5加密的网址:http://www.cmd5.com/

感谢链接:
http://blog.sina.com.cn/s/blog_693de6100101kcu6.html

https://github.com/JieweiWei/md5

(0)

相关推荐

  • C++中md5 算法实现代码

    在网上找了份c++ MD5的代码,就简单保存一下: 首先md5.h #ifndef MD5_H #define MD5_H #include <string> #include <fstream> /* Type define */ typedef unsigned char byte; typedef unsigned long ulong; using std::string; using std::ifstream; /* MD5 declaration. */ class

  • c++实现MD5算法实现代码

    测试结果和百度百科测试例子一致. 实现过程中需要注意事项:最后把四个变量A B C D 链接成结果时 ,注意变量高低位的先后顺序,具体参考 LinkResult()方法. md5.h #ifndef _MD5_H_ #define _MD5_H_ #include <iostream> #include <string> using namespace std; class MD5 { public: typedef unsigned char uchar8; //make sur

  • VC++ 字符串String MD5计算小工具 VS2008工程

    基于字符串加密的MD5算法,VS2008 VC++,多字节编译工程.主要代码如下,实现了ANSI字符串加密与Unicode字符串加密. 运行效果如下: 核心代码: void CEncryptByMd5Dlg::OnButtonOk() { // TODO: Add your control notification handler code here UpdateData(true); unsigned int len=0; char *cTemp =NULL; if(m_bType==0) {

  • C++ MD5的源码实例详解

    C++ MD5源码: md5.h: #ifndef MD5_H #define MD5_H #include <string> #include <fstream> /* Type define */ typedef unsigned char byte; typedef unsigned int uint32; using std::string; using std::ifstream; /* MD5 declaration. */ class MD5 { public: MD

  • Java与C++实现相同的MD5加密算法简单实例

    1.Java版 package com.lyz.utils.common; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * MD5加密 * @author liuyazhuang */ public class MD5Hash { public static String md5

  • C/C++ MD5算法的实现代码

    在逆向程序的时候,经常会碰到加密的算法的问题,前面分析UC的逆向工程师的面试题2的时候,发现使用了MD5的加密算法(MD5算法是自己实现的,不是使用的算法库函数).尤其是在逆向分析网络协议的时候,一般的程序使用的加密算法都是使用的库函数提供的算法,有些程序使用的算法是自己实现的:相对来说使用函数库提供的加密函数的算法相对来说比较好识别,因为有算法常见函数在:但是如果不是使用的函数库提供的加密的函数而是自己去实现某些算法话,识别起来有一定的难度,这就需要你对函数的加密原理以及流程还算法的特征比较熟

  • php 二维数组快速排序算法的实现代码

    php 二维数组快速排序算法的实现代码 二维数组排序算法与一维数组排序算法基本理论都是一样,都是通过比较把小的值放在左变的数组里,大的值放在右边的数组里在分别递归. 实例代码: <?php class Bubble { private function __construct() { } private static function sortt($data) { if (count ( $data ) <= 1) { return $data; } $tem = $data [0]['sco

  • vue2.0中goods选购栏滚动算法的实现代码

    不多说,直接代码,以便以后重复利用: <script type="text/ecmascript-6"> import BScroll from 'better-scroll'; const ERR_OK = 0; export default { props: { sell: { type: Object } }, data() { return { goods: [], listHeight: [], scrollY: 0 }; }, computed: { curre

  • python常用排序算法的实现代码

    这篇文章主要介绍了python常用排序算法的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 排序是计算机语言需要实现的基本算法之一,有序的数据结构会带来效率上的极大提升. 1.插入排序 插入排序默认当前被插入的序列是有序的,新元素插入到应该插入的位置,使得新序列仍然有序. def insertion_sort(old_list): n=len(old_list) k=0 for i in range(1,n): temp=old_lis

  • php计数排序算法的实现代码(附四个实例代码)

    计数排序只适合使用在键的变化不大于元素总数的情况下.它通常用作另一种排序算法(基数排序)的子程序,这样可以有效地处理更大的键. 总之,计数排序是一种稳定的线性时间排序算法.计数排序使用一个额外的数组C ,其中第i个元素是待排序数组 A中值等于 i的元素的个数.然后根据数组C 来将A中的元素排到正确的位置. 通常计数排序算法的实现步骤思路是: 1.找出待排序的数组中最大和最小的元素: 2.统计数组中每个值为i的元素出现的次数,存入数组C的第i项: 3.对所有的计数累加(从C中的第一个元素开始,每一

  • 使用Python处理KNN分类算法的实现代码

    目录 KNN分类算法的介绍 测试数据 Python代码实现 结果分析 简介: 我们在这世上,选择什么就成为什么,人生的丰富多彩,得靠自己成就.你此刻的付出,决定了你未来成为什么样的人,当你改变不了世界,你还可以改变自己. KNN分类算法的介绍 KNN分类算法(K-Nearest-Neighbors Classification),又叫K近邻算法,是一个概念极其简单,而分类效果又很优秀的分类算法. 他的核心思想就是,要确定测试样本属于哪一类,就寻找所有训练样本中与该测试样本“距离”最近的前K个样本

  • Spectral clustering谱聚类算法的实现代码

    目录 1.作者介绍 2.关于谱聚类的介绍 2.1 谱聚类概述 2.2 无向权重图 2.3 邻接矩阵 2.4 相似矩阵 2.5 度矩阵 2.6 拉普拉斯矩阵 2.7 K-Means 3.Spectral clustering(谱聚类)算法实现 3.1 数据集 3.2 导入所需要的包 3.3 获取特征值和特征向量 3.4 利用K-Means聚类 3.5 完整代码 4.参考 1.作者介绍 刘然,女,西安工程大学电子信息学院,2021级研究生研究方向:图像处理电子邮件:1654790996@qq.com

  • PHP 冒泡排序算法的实现代码

    基本概念 冒泡排序的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面.即首先比较第1 个和第2个数,将小数放前,大数放后.然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后.重复以上过程,仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再大于第2个数),将小数放前,大数放后,一直比较到最小数前的一对相邻数,将小数放前,大数放后,第二趟结束,在倒数第二个数中得到一个新的最小数.如此下去,直至最终完成排序. 由

  • python冒泡排序算法的实现代码

    1.算法描述:(1)共循环 n-1 次(2)每次循环中,如果 前面的数大于后面的数,就交换(3)设置一个标签,如果上次没有交换,就说明这个是已经好了的. 2.python冒泡排序代码 复制代码 代码如下: #!/usr/bin/python# -*- coding: utf-8 -*- def bubble(l):    flag = True    for i in range(len(l)-1, 0, -1):        if flag:             flag = False

  • 解析C#彩色图像灰度化算法的实现代码详解

    代码如下所示: 复制代码 代码如下: public static Bitmap MakeGrayscale(Bitmap original)        {            //create a blank bitmap the same size as original            Bitmap newBitmap = new Bitmap(original.Width, original.Height);            //get a graphics object

随机推荐