导航:首页 > 源码编译 > HMPP算法源码

HMPP算法源码

发布时间:2022-10-29 17:51:18

1. 什么是algor ithm和程序

算法是用来解决一个问题的程序或者公式。“算法”(algorithm)这个词源自生活在公元9世纪的波斯数学家Al-Khowarizmi。一个电脑程序可以被看成是一个精心设计的算法。在数学和电脑学科,一个算法通常意味着一个可以解决循环问题的小程序。
程序序(program)是为实现特定目标或解决特定问题而用计算机语言编写的命令序列的集合。
程序(港台称之为程式) program(me)或procere
chénɡ xù
概念1.:为进行某活动或过程所规定的途径。
概念2.程序是由序列组成的,告诉计算机如何完成一个具体的任务。由于现在的计算机还不能理解人类的自然语言,所以还不能用自然语言编写计算机程序。

2. 泰坦的软件支持

参见:NVIDIA CUDA
不同于以往以中央处理器作主要数据处理单元或以图形处理器辅助处理数据的超级电脑,泰坦超级电脑以图形处理器为主要的数据处理单元。在初期,不少专案的程序源码一般重新编写或编译以方便泰坦的通用图形处理器运行,而且还要求这些源码能兼容于以中央处理器为主的系统,以便专案可以不仅可以由泰坦进行处理,还能供其它仍使用传统中央处理器架构的超级电脑运行。Oak Ridge Leadership Computing Facility(OLCF)还成立了Center for Accelerated Application Readiness(加速申请中心,CAAR)来帮助科学研究者们重写或重新编译他们所写的代码以供泰坦运作之,并且在英伟达总部举办开发者研习会,让研究人员和程序员学习并使用泰坦和其它类似的超级电脑的架构、编译器和应用程序。
以使研究者们可以和以前一样,以Fortran、C或C++来编写他们的代码而无须学习新的编程语言,并且编译器可以将这些代码编译为通用图形处理器可以高效运作的程序。
“加速编译器指令”包括OpenACC、PGI Accelerator、CAPS HMPP Workbench;“低级图形处理器编程语言”有NVIDIA C for CUDA、PGI CUDA Fortran、OpenCL。这些工具中有部分甚至允许开发者在不了解关于NVIDIA CUDA的知识的情况下使用。在泰坦上适用的编译器有PGI(Portland Group Compiler Suite,默认使用这个)、GCC、CCE(Cray Compiling Environment)以及英特尔提供的编译器。
即所谓的多核多线程优化,只是更深入、更适合通用图形处理器的架构特性(通用图形处理器拥有比中央处理器多得多的线程和更好的运算并发性)。不过这样的程序源码优化也适用于传统以中央处理器为基础的机器上,这些机器也可以从中获得性能提升。天体物理学家兼程序员Bronson Messer,表示“一个应用程序要将泰坦的性能发挥至极限,必须寻求方法来使通用图形处理器满负载运作,需要明确的是通用图形处理器尽管处理速度很快,但灵活度显然不如中央处理器。”作业管理者也发现,一些计划专案的代码在重写后,在那些不是基于图形处理器的机器上的效率也变得大有提升,“Denovo”专案的程序在基于中央处理器的机器上甚至还比原先获得双倍的性能提升表现。
要求调用图形处理器的进行运算作业的代码变更量因不同专案而变。根据负责NRDF专案的梅瑟博士(Dr. Messer)的意见,他们的代码中调用图形处理器的算法源码只占整个代码中很小的百分比,因为这些程序算法的运算都相对简单,但处理进程重复而且具有平行性。NRDF的程序用CUDA Fortran写成,CUDA Fortran是Fortran语言链接CUDA指令扩充库(NVIDIA CUDA库)给予图形处理器使用的Fortran改进版本。

3. 求教:蚁群算法选择最短路径问题

这个例子其实是当初数模比赛时用来完成碎片拼接的,但其所用到原理还是求解最短路径的原理。但这里的最短路径和数据结构中最短路径有一定的区别。在数据结构中,对于最短路径的求解常用的一般有Dijkstra算法与Floyd算法,但对于要求出一条经过所有的点的并且要求路径最短,这些算法还是有一定的局限性的。而蚁群算法则很好地满足了这些条件。话说回来,很想吐槽一下网络流传的一些蚁群算法的例子,当初学习这个时候,身边也没有相关的书籍,只好到网上找例子。网上关于这个算法源代码的常见的有2个版本,都是出自博客,但是在例子都代码是不完整的,缺失了一部分,但就是这样的例子,居然流传甚广,我很好奇那些转载这些源码的人是否真的有去学习过这些,去调试过。当然,我下面的例子也是无法直接编译通过的,因为涉及到图像读取处理等方面的东西,所以就只贴算法代码部分。但是对于这个问题蚁群算法有一个比较大的缺点,就是收敛很慢,不过对于数量小的路径,效果还是很好的。function bestqueue =aco1(nt,nc_max,m ,st, sd ,Alpha ,Beta ,Rho ,Q,gethead,getend)%参数解释:%nt 路径所经过的点的个数;%nc_max 迭代的次数;%m 蚂蚁的个数;%st 起点序号;%sd 终点序号;%Alpha 信息素系数;�ta 启发因子系数;%Rho 蒸发系数;% Q 信息量;%gethead getend 是用来求距离矩阵的,可根据实际情况修改
% nt = 209;%碎片个数full = zeros(nt,nt);tic;%初始化距离矩阵for i =1:nt for t = 1:nt if i ~= t full(i,t) = sum(abs(getend(:,i) - gethead(:,t))); else full(i,t) = inf; end endend% a =full(156,187)eta = 1./full;%启发因子,取距离的倒数% eta% e = eta(4,2)tau = ones(nt,nt);%信息素矩阵% tabu = zeros(nt,nt);%禁忌矩阵,取蚂蚁数量和碎片数量一致,以减少迭代次数nc =1;%初始化迭代次数;rbest=zeros(nc_max,nt);%各代最佳路线rbest(:,1) = (linspace(st,st,nc_max))';rbest(:,nt) =(linspace(sd,sd,nc_max))'; lbest=zeros(nc_max,1);%各代最佳路线的长度pathlen = 0;%临时记录每代最佳路线长度stime = 1;%记录代数进度for i = 1:nc_max % 代数循环 delta_tau=zeros(nt,nt);%初始化改变量 stime for t = 1:m % 对蚂蚁群体的循环, tabu=zeros(1,nt);%禁忌向量,标记已访问的碎片,初试值设为0,访问之后则变为1; viseted = zeros(1,nt);%记录已访问的元素的位置 tabu(st) = 1;%st为起点,在此表示为碎片矩阵的编号,因为已经将蚁群放在起点,故也应将禁忌向量和位置向量的状态进行修改 tabu(sd) =1;%同上 visited(nt) = sd ;%同上; visited(1) = st;%同上; ht = 0; for r = 2:nt-1 %记录了还没访问的图片编号 vp = 1;%visited指示量 pp = [];%置空的概率向量 jc = 0; %获取尚未访问的位置的向量。 wv = zeros( nt -2 - ht ); for k =1 : nt if tabu(k) == 0 jc = jc +1; wv(jc) = k; end end% a =(tau(visited(end),ju(3))^Alpha)*(eta(visited(end),ju(3))^Beta)% visited(end) %计算选择的概率 for k=1:length(wv) pp(k)=(tau(visited(vp),wv(k))^Alpha)*(eta(visited(vp),wv(k))^Beta);%下一张碎片的选择概率计算,p =(信息素^信息素系数)*(启发因子^启发因子系数) end pp=pp./(sum(pp));%归一化 pcum =cumsum(pp); psl = find(pcum >= rand);%轮盘赌法 to_visit= wv(psl(1)) ;%完成选点 tabu(to_visit) =1; visited(r) = to_visit; ht =ht +1;%已访问碎片个数变化 vp =vp+1; end %路径变化信息 %对单个蚂蚁的路径进行统计 sum1 =0; for pr = 1:nt -1 x = visited(pr); y = visited(pr+1) ; sum1 =sum1 + full(x,y); end% vcell{t} =visited;%元胞记录每个蚂蚁的路径,即碎片顺序;% msum(t) = sum1; %信息素变化; for ww=1:(nt-1) delta_tau(visited(ww),visited(ww+1))=delta_tau(visited(ww),visited(ww+1)) + Q/sum1; end% delta_tau(visited(end),visited(1))=delta_tau(visited(end),visited(1))+Q/(sum1/100);% if t == m & i == nc_max % bestqueue = visited% end if t == m bestqueue = visited end end tau=(1-Rho).*tau+delta_tau; %完成信息素的更新,找出现有的最新的最佳路径,即信息素最多的路径; stime =stime +1;end toc;

4. 求五子棋AI算法

在本次“五子棋“程序的编写中,只编写了人机对弈部分,运用了博弈树进行搜索,在选取最优的走步时使用极大极小分析法,考虑到搜索的时间复杂度和空间复杂度,在程序中只进行了2步搜索,即计算机在考虑下一步的走法时,只对玩家进行一步的推测。(程序中的棋盘规格为15*15)
下面对具体做法进行描述:
1. 数据结构定义:
棋盘定义:int board[15][15];
在15*15的棋盘上,获胜的情况总共有572种,
如:
* * * * * ……
…… …… …… …… …… ……
…… …… …… …… …… ……
…… …… …… …… …… ……
…… …… …… …… …… ……
…… …… …… …… …… ……
中的第一行“*“所代表的格子就是一种获胜组合。
计算机和玩家的获胜组合情况bool ctable[15][15][572],
bool ptable[15][15][572],来表示棋盘上的各个位置都在那种获胜组合中。
计算机和玩家在各个获胜组合中所填入的棋子数int win[2][572],如有一方在某一获胜组合的棋子数达到5个,该方即获胜。
Bool player:是否轮到玩家下棋
Bool computer:是否轮到计算机下棋
Bool start:游戏是否开始
Bool pwin:玩家是否获胜
Bool cwin:计算机是否获胜
CPoint m_pplastpos;//玩家走的前一步棋
CPoint m_pclastpos;//计算机走的前一步棋
为便于说明程序的主要算法,这里先说本程序中估价函数的选取方法:
e=p1+p2;
p1为下完当前这步棋时计算机的得分;p2为下完当前这步棋时玩家的得分(p2其实为负),这样做即考虑了进攻的因数,由考虑了防守的因数,两个方面都进行了考虑,防止计算机只考虑进攻而忽略防守,同时也防止计算机只考虑防守而忽略进攻,从而达到比较好的情况。
2.主要流程描述
其程序流程图如下:

(1) 初始化棋盘:判断哪方先开始,(2) 初始化计算机和玩家的获胜组合情况
bool ctable[15][15][572],bool ptable[15][15][572]
void CMyChessDlg::InitializeBoard()
{
//初始时双方都还没下子
int i,j,count=0,k;
m_pclastpos.x=-1;
m_pclastpos.y=-1;
m_pplastpos.x=-1;
m_pplastpos.y=-1;
start=true;
//判断哪方先开始
if(m_bwfirst)
{
player=false;
computer=true;
}
else
{
player=true;
computer=false;
}
pwin=cwin=false;
//初始化计算机和玩家的获胜组合情况
for(i=0;i<15;i++)
for(j=0;j<15;j++)
for(k=0;k<572;k++)
{
ptable[i][j][k]=false;
ctable[i][j][k]=false;
}
for(i=0;i<2;i++)
for(j=0;j<572;j++)
win[i][j]=0;
for(i=0;i<15;i++)
for(j=0;j<15;j++)
board[i][j]=2;
for(i=0;i<15;i++)
for(j=0;j<11;j++)
{
for(k=0;k<5;k++)
{
ptable[j+k][i][count]=true;
ctable[j+k][i][count]=true;
}
count++;
}
for(i=0;i<15;i++)
for(j=0;j<11;j++)
{
for(k=0;k<5;k++)
{
ptable[i][j+k][count]=true;
ctable[i][j+k][count]=true;
}
count++;
}
for(i=0;i<11;i++)
for(j=0;j<11;j++)
{
for(k=0;k<5;k++)
{
ptable[j+k][i+k][count]=true;
ctable[j+k][i+k][count]=true;
}
count++;
}
for(i=0;i<11;i++)
for(j=14;j>=4;j--)
{
for(k=0;k<5;k++)
{
ptable[j-k][i+k][count]=true;
ctable[j-k][i+k][count]=true;
}
count++;
}
}
(3) 给出下了一个子后的分数:
int CMyChessDlg::GiveScore(int type, int x, int y)
{
int i,score=0;
for(i=0;i<572;i++)
{
//计算机下
if(type==1)
{
if(ctable[x][y][i])
{
switch(win[1][i])
{
case 1:
score+=5;
break;
case 2:
score+=50;
break;
case 3:
score+=100;
break;
case 4:
score+=10000;
break;
default:
break;
}
}
}
//人下
else
{
if(ptable[x][y][i])
{
switch(win[0][i])
{
case 1:
score-=5;
break;
case 2:
score-=50;
break;
case 3:
score-=500;
break;
case 4:
score-=5000;
break;
default:
break;
}
}
}
}
return score;
}
(4) 核心程序 ,(5) 即计算机如何运用极小极大法分析,(6) 选取最优走法,(7)
在程序中极小极大法即体现在两个while循环前后及之间的内容,其估价函数的体现在ctemp+pscore中
void CMyChessDlg::ComTurn()
{
//bestx,best为当前最佳位置,i,j是人能下的各种位置;pi,pj是计算机能下的各种位置
Int bestx,besty,i,j,pi,pj,ptemp,ctemp,pscore=10,cscore=-10000,
ctempboard[15][15],ptempboard[15][15];
int m,n,temp1[20],temp2[20];//暂存第一步搜索的信息
if(start)
{
if(board[7][7]==2)
{
bestx=7;
besty=7;
}
else
{
bestx=8;
besty=8;
}
start=false;
}
else
{//寻找最佳位置
GetBoard(ctempboard,board);
while(SearchBlank(i,j,ctempboard))
{//进行第一步查找
n=0;
pscore=10;
GetBoard(ptempboard,board);//获取当前棋盘状态
ctempboard[i][j]=3;//标记已被查找
ctemp=GiveScore(1,i,j);
for(m=0;m<572;m++)
{//暂时更改玩家信息
if(ptable[i][j][m])
{
temp1[n]=m;
ptable[i][j][m]=false;
temp2[n]=win[0][m];
win[0][m]=7;
n++;
}
}
ptempboard[i][j]=1;
/***********************************************/
/* 是否胜利,是返回1 */
int victory(int player)
{
int column=E_column,row=E_row;
int left_sum=0,right_sum=0;
int top_sum=0,down_sum=0;
int left_top_sum=0,right_down_sum=0;
int right_top_sum=0,left_down_sum=0;
int i,j;

for (i=column;i>=column-4 && i>0;i--)
if (chess_map[i-1][row-1]==player)
left_sum++;
else
break;
for (i=column;i<=column+4 && i<17;i++)
if (chess_map[i-1][row-1]==player)
right_sum++;
else
break;
if ((left_sum+right_sum)==6)
return 1;

for (j=row;j>=row-4 && j>0;j--)
if (chess_map[column-1][j-1]==player)
top_sum++;
else
break;
for (j=row;j<=row+4 && j<17;j++)
if (chess_map[column-1][j-1]==player)
down_sum++;
else
break;
if ((top_sum+down_sum)==6)
return 1;

for (i=column,j=row;i>=column-4 && j>=row-4 && i>0 && j>0;i--,j--)
if (chess_map[i-1][j-1]==player)
left_top_sum++;
else
break;
for (i=column,j=row;i<=column+4 && j<=row+4 && i<17 && j<17;i++,j++)
if (chess_map[i-1][j-1]==player)
right_down_sum++;
else
break;
if ((left_top_sum+right_down_sum)==6)
return 1;

for (i=column,j=row;i<=column+4 && j>=row-4 && i<17 && j>0;i++,j--)
if (chess_map[i-1][j-1]==player)
right_top_sum++;
else
break;
for (i=column,j=row;i>=column-4 && j<=row+4 && j<17 && i>0;j++,i--)
if (chess_map[i-1][j-1]==player)
left_down_sum++;
else
break;
if (right_top_sum+left_down_sum==6)
return 1;
return 0;
}

/**********************AI**********************/
int AI(int *m,int *n)
{
int bestx=8,besty=8;
long f_score=0,score=0;
int i,j;
int a[8],b[8];
for (i=0;i<8;i++)
{a[i]=0,b[i]=0;}

for (i=0;i<16;i++)
for (j=0;j<16;j++)
{
score=0;
if (chess_map[i][j]==0)
{
/********************进攻分数**********************/
chess_map[i][j]=computer;
for (i=column;i>=column-4 && i>0;i--)
if (chess_map[i-1][row-1]==computer)
a[0]++;
else
break;
for (i=column;i<=column+4 && i<17;i++)
if (chess_map[i-1][row-1]==computer)
a[1]++;
else
break;
for (j=row;j>=row-4 && j>0;j--)
if (chess_map[column-1][j-1]==computer)
a[2]++;
else
break;
for (j=row;j<=row+4 && j<17;j++)
if (chess_map[column-1][j-1]==computer)
a[3]++;
else
break;
for (i=column,j=row;i>=column-4 && j>=row-4 && i>0 && j>0;i--,j--)
if (chess_map[i-1][j-1]==computer)
a[4]++;
else
break;
for (i=column,j=row;i<=column+4 && j<=row+4 && i<17 && j<17;i++,j++)
if (chess_map[i-1][j-1]==computer)
a[5]++;
else
break;
for (i=column,j=row;i<=column+4 && j>=row-4 && i<17 && j>0;i++,j--)
if (chess_map[i-1][j-1]==computer)
a[6]++;
else
break;
for (i=column,j=row;i>=column-4 && j<=row+4 && j<17 && i>0;j++,i--)
if (chess_map[i-1][j-1]==computer)
a[7]++;
else
break;
for (i=0;i<8;i++)
{
switch(a[i]-1)
{
case 1:
score+=5;
break;
case 2:
score+=50;
break;
case 3:
score+=100;
break;
case 4:
score+=10000;
break;
default:
break;
}
}
/********************进攻分数**********************/
/********************防守分数**********************/
chess_map[i][j]=elva6401;
for (i=column;i>=column-4 && i>0;i--)
if (chess_map[i-1][row-1]==elva6401)
b[0]++;
else
break;
for (i=column;i<=column+4 && i<17;i++)
if (chess_map[i-1][row-1]==elva6401)
b[1]++;
else
break;
for (j=row;j>=row-4 && j>0;j--)
if (chess_map[column-1][j-1]==elva6401)
b[2]++;
else
break;
for (j=row;j<=row+4 && j<17;j++)
if (chess_map[column-1][j-1]==elva6401)
b[3]++;
else
break;
for (i=column,j=row;i>=column-4 && j>=row-4 && i>0 && j>0;i--,j--)
if (chess_map[i-1][j-1]==elva6401)
b[4]++;
else
break;
for (i=column,j=row;i<=column+4 && j<=row+4 && i<17 && j<17;i++,j++)
if (chess_map[i-1][j-1]==elva6401)
b[5]++;
else
break;
for (i=column,j=row;i<=column+4 && j>=row-4 && i<17 && j>0;i++,j--)
if (chess_map[i-1][j-1]==elva6401)
b[6]++;
else
break;
for (i=column,j=row;i>=column-4 && j<=row+4 && j<17 && i>0;j++,i--)
if (chess_map[i-1][j-1]==elva6401)
b[7]++;
else
break;
for(i=0;i<8;i++)
{
switch(b[i]-1)
{
case 1:
score-=5;
break;
case 2:
score-=50;
break;
case 3:
score-=500;
break;
case 4:
score-=5000;
break;
default:
break;
}
}
/********************防守分数**********************/
chess_map[i][j]=0;
if (score>f_score)
{
bestx=i+1;
besty=j+1;
f_score=score;
}
}
}
E_column=bestx,* m=bestx;
E_row=besty,* n=besty;
chess_map[bestx-1][besty-1]=computer;
}
/**********************AI***********************/

/***********************************************/
/* main */
int main()
{
int gdriver=DETECT,gmode;
initgraph(&gdriver,&gmode," ");
setbkcolor(BLUE);
init();
column=9,row=9;
chess_map[column-1][row-1]=computer;
draw_chess(computer);
while(1)
{
init_col_row();
flag=1;
while(flag==1)
{
move_chess(elva6401);
getch();
}
draw_chess(elva6401);
if(victory(elva6401))
{
outtextxy(550,400,"You win the game\n");
getch();
return 0;
}
AI(&column,&row);
draw_chess(computer);
if(victory(computer))
{
outtextxy(550,400,"You lost the game\n");
getch();
return 0;
}
}
}
// ChangeStatus(ptempboard);
pi=i;
pj=j;
while(SearchBlank(i,j,ptempboard))
{//进行第二不查找
ptempboard[i][j]=3;//标记已被查找
ptemp=GiveScore(0,i,j);
if(pscore>ptemp)//此时为玩家下子,运用极小极大法时应选取最小值
pscore=ptemp;
}
for(m=0;m<n;m++)
{//恢复玩家信息
ptable[pi][pj][temp1[m]]=true;
win[0][temp1[m]]=temp2[m];
}
//ctemp+pscore为实际估价函数
if(ctemp+pscore>cscore) //此时为计算机下子,运用极小极大法时应选取最最大值
{
cscore=ctemp+pscore;
bestx=pi;
besty=pj;
}
}
}
board[bestx][besty]=1;
if(m_pclastpos.x!=-1&&m_pclastpos.y!=-1)
{//画前一棋子
if(!m_bwfirst)
DrawBlackChess(m_pclastpos.x,m_pclastpos.y);
else
DrawWhiteChess(m_pclastpos.x,m_pclastpos.y);
}

if(!m_bwfirst)
DrawNowBlack(bestx,besty);
else
DrawNowWhite(bestx,besty);
m_pclastpos.x=bestx;
m_pclastpos.y=besty;
for(i=0;i<572;i++)
{//修改计算机下子后,棋盘的变化状况
if(ctable[bestx][besty][i]&&win[1][i]!=7)
win[1][i]++;
if(ptable[bestx][besty][i])
{
ptable[bestx][besty][i]=false;
win[0][i]=7;
}
}
computer=false;
player=true;
}
(8) 玩家下棋:(其中坐标(9) 加减目的是调整图片的位置和棋盘对齐)
void CMyChessDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
int x,y,tx,ty;
// TODO: Add your message handler code here and/or call default
if(player&&point.x<=535&&point.y<=535)//判断是否在有效区域
{
tx=x=point.x-24;
ty=y=point.y-25;
while(tx>=36)
tx-=36;
while(ty>=36)
ty-=36;
tx+=x/36;
ty+=y/36;
if(tx>18)
x=x/36+1;
else
x=x/36;
if(ty>18)
y=y/36+1;
else
y=y/36;
if(board[x][y]==2)
{
board[x][y]=0;//设为玩家的棋子
if(m_pplastpos.x!=-1&&m_pplastpos.y!=-1)
{
if(!m_bwfirst)
DrawWhiteChess(m_pplastpos.x,m_pplastpos.y);
else
DrawBlackChess(m_pplastpos.x,m_pplastpos.y);
}

if(!m_bwfirst)
DrawNowWhite(x,y);
else
DrawNowBlack(x,y);
m_pplastpos.x=x;
m_pplastpos.y=y;
for(int i=0;i<572;i++)//修改玩家下子后棋盘状态的变化
{
if(i==80)
i=80;
if(ptable[x][y][i]&&win[0][i]!=7)
win[0][i]++;
if(ctable[x][y][i])
{
ctable[x][y][i]=false;
win[1][i]=7;
}
}
player=false;
computer=true;
}
}
CDialog::OnLButtonDown(nFlags, point);
}

5. 张泽民教授课题组再发Cell,用到的单细胞技术了解一下

4月16日,百奥智汇创始人、科学顾问张泽民教授在北京大学的课题组与合作者在国际顶级学术期刊《Cell》上发表了题为"Single-Cell Analyses Inform Mechanisms of Myeloid-Targeted Therapies in Colon Cancer"的文章,利用单细胞转录组测序技术对结直肠癌患者的肿瘤微环境,特别是浸润髓系细胞类群首次进行了系统性的刻画,同时利用小鼠模型,对anti-CSF1R抑制剂和anti-CD40激动剂两种靶向髓系细胞的免疫治疗策略潜在的作用机理给出了解释。

该研究建立了结合肿瘤患者及小鼠模型的单细胞转录组来研究肿瘤免疫治疗的范例,为人们研究其他疾病中免疫细胞以及开发新的治疗方案提供了思路。

对于该研究,上海市免疫学研究所苏冰所长、上海交通大学医学院叶幼琼研究员等相关专家点评道:该工作全面地解析结肠癌的肿瘤微环境细胞图谱,阐明细胞与细胞之间的相互作用,对靶向肿瘤免疫微环境为基础的肿瘤治疗提供了更详细的理论基础,为今后靶定髓系细胞的精准治疗提供助力,具有重要的临床转化意义。

在该研究中,研究者共使用了Smart-seq2、10x 3′ Gene Expression、10x V(D)J + 5′ Gene Expression等 3种单细胞测序技术 ,以及tSNE、UMAP、PCA、RNA velocity、URD、PAGA、STARTRAC、GSVA富集分析、热图、小提琴图、气泡热图、轨迹图、Circos图、火山图、生存分析等 十多种生物信息学分析及展示方法。

值得一提的是, 这些实验技术和分析方法,百奥智汇皆可实现。

下面,百奥我就为大家详细解析,带大家了解这些技术和方法是如何在研究中应用的。

1.10x Genomics和Smart-seq2技术比较

该研究首先评估并比较了10x Genomics和Smart-seq2两种单细胞测序技术的结果。结果显示,与10x scRNA-seq平台相比,Smart-seq2捕获了更多的基因,包括细胞因子,CD分子,配体/受体和转录因子,并且显示出较弱的批次效应 ,从而可以对调节途径进行更深入的分析(图2),而10x平台则获得了更多的分群。因此,作者将两种技术同时使用,从而能够最大化地确定细胞类型或稀有种群的数量,改善细胞聚类的结果,得出更准确的结论。

2.tSNE降维——展示分群、基因表达模式、组织分布等多层信息

该研究使用无监督聚类、PCA、CGA等方法对来自18位CRC患者肿瘤、邻近组织和血液样本的10× 3′ Gene Expression ( 43,817个细胞)和Smart-seq2(10,468)单细胞测序结果进行整合聚类分析,然后用tSNE进行降维展示,分别得到38个和36个群,包括6个内皮细胞群,2个成纤维细胞群,13个髓系细胞群,4个ILC群,18个T细胞群和5个B细胞群等(图3)。

对于淋巴细胞,研究通过特异的的免疫球蛋白重链特征基因加以区分(图4)。

同时,研究还在tSNE结果中展示了各细胞的组织分布情况(图5)。

对于Smart-seq2非免疫细胞的测序结果,该研究利用tSNE将其分为12个亚群,包括4个恶性细胞亚群和8个非恶性细胞亚群(图6)。其中,由推断的拷贝数变异(CNV)定义的恶性细胞表现出高度的基因表达异质性,形成了患者特异性的分群(图7)。

3.热图、气泡热图——展示细胞间基因表达模式的差异

单个tSNE图或组图可展示单个或数个基因在不同细胞群中的表达情况,但在展示多个样本大量基因的全局表达情况时就相对吃力。此时就需要用到热图。而气泡热图则是在热图的基础上加入了基因表达细胞在特定细胞群中占比的信息,从而对细胞群进行更详细的表征。

在该研究中,作者用热图展示了10x测序分析得到的38个白细胞群中的差异基因表达差异(图8),以及整合10x和Smart-seq2测序分析得到的48个群的基因表达差异(图9)。

研究还分析了13个髓系细胞中的特征基因表达情况(其中9个以气泡热图展示),并据此将它们区分为肥大细胞(hM01),树突状细胞(hM02-04),单核细胞(hM05-07,hM11),组织驻留性巨噬细胞(hM08-10)和 肿瘤相关巨噬细胞(TAMs,hM12-13)。

4.扩散图、RNA velocity、URD、PAGA——推断和展示细胞发育轨迹

为进一步探索 TAMs 的来源,该研究利用扩散图中嵌入的RNA velocity对随机选择的单核细胞和巨噬细胞的发育轨迹进行推断和展示,鉴定出了从表达CD14的单核细胞向FCN1+ 单核样细胞和不同的巨噬细胞群体的强烈定向流动(图11),体现二者在发育上的前后顺序。

进一步利用URD和PAGA这两种正交算法分析巨噬细胞的转录轨迹,发现巨噬细胞发育成TAMs(图12,图13)。

综合上述轨迹推断结果,研究发现TAM主要来自独特的肿瘤浸润性单核样细胞前体。其中, C1QC+ 和 SPP1+ TAM都从浸润肿瘤的单核细胞样前体形成,而 SPP1+ TAM也可能源自 NLRP3+ RTM(图14)。

5.火山图、富集分析、热图、URD图——多角度展示两类TAMs差异

对于两类在发育轨迹上存在显着差异的TAMs,作者进一步使用热图、火山图、富集分析等方法进行了分析,从多角度揭示了它们的差异。

由于细胞的发育轨迹受转录调控网络控制,作者先分析了两类TAMs转录因子的表达差异,结果以热图显示。其中,C1QC+ TAMs显示出MAF/MAFB和FOS/JUNS高表达,而PP1+ TAMs则高表达CEBPB和ZEB2。

然后,作者又用火山图展示两类TAMs中显着差异表达的基因。该图包含两个维度,其中纵轴P value体现显着性,横轴fold change展示差异性。

结果显示,C1QC+ TAMs显示出补体C1Q、TREM2、MERTK和CD80等基因的高表达, 而SPP1+ TAMs显示出SPP1、MARCO和VEGFA的特异性表达。

随后,作者又使用基因集合变异分析(GSVE)分析了两类TAMs在通路上的差异。GSVE是一种以非监督方式对一个群体评估通路活性差异的基因集富集(GSE)分析方法。

该研究的结果显示,SPP1+ TAMs显示出肿瘤血管生成,ECM受体相互作用、肿瘤脉管系统、大肠腺瘤和转移性肝癌等通路的特异性富集,而C1QC+ TAMs则显示出补体激活以及抗原加工和呈递途径的富集(图17)。

此外,SPP1 + TAMs还显示了大肠腺瘤和转移性肝癌通路的特异性富集和相关基因的表达(图17和图18),表明在它们CRC中有促癌/促转移作用。

6.相互作用网络图和Circos图——展示细胞间相互作用、受体配体相互作用

更进一步地,作者在CRC中建立了细胞间相互作用网络图。将该研究中的单细胞测序数据集与GTEx、TCGA的组织整体RNA测序数据集进行整合分析,发现TAM和cDC作为预测网络的核心,与其他细胞类型的联系最多(图19,图20)。其中,C1QC+ TAM和两组cDC主要与其他免疫细胞(尤其是T细胞亚群)相互作用(图20),提示其在抗肿瘤T细胞应答中起调节作用。

再进一步的细胞群间的受体——配体相互作用分析显示,在与髓系细胞和T细胞有关的配体-受体对中,CXCL10-CXCR3在C1QC + TAM中富集,暗示了C1QC+ TAM具有募集或激活T细胞的潜在作用。而SPP1+ TAMs中富集的SPP1-ITGAV、SDC2-MMP2、FN1-ITGA5等配体-受体对,则暗示了其在可能与某些整合蛋白相互作用,以促进CRC的肿瘤发生。

7.相似性分析、热图——展示跨物种的细胞群相似性

为了将上述对人髓系细胞异质性的研究发现与临床应用相结合,作者接下来将相同的实验和分析方法用于两种对肿瘤免疫治疗的小鼠模型中,其中Renca对CSF1R阻断抗体敏感,而MC38对CD40激动剂抗体敏感(图21)。

作者使用10x Genomics平台对免疫治疗后小鼠的肿瘤中分离出的免疫细胞进行了单细胞转录组测序,并与人髓系细胞群进行了相似性分析,确定了多个跨物种相对应的髓系种群,包括两种cDC群和两种TAM群(图22)。

此外,对小鼠TAM群进行与人类TAM群相同的途径分析发现,小鼠TAM群体也基于它们的血管生成,低氧和T细胞相互作用基因特征而分离(图23)。这些数据表明人类CRC患者和小鼠肿瘤模型之间存在功能相似的TAM群体。

8.细胞丰度、生存分析——体现不同细胞类群的抗药性

进一步的耐药性研究显示,抗CSF1R治疗后F4/80高表达的巨噬细胞优先减少(图24),说明不同的巨噬细胞群体对抗CSF1R治疗的敏感性不同。同时,治疗后小鼠细胞群中mC12和mM14簇几乎完全丢失,TAM簇mM11,mM13和mM15的减少最小(图24),说明TAMs对CSF1R阻断的治疗具有抗性。同时,抗CSF1R的TAM亚群优先表达参与血管生成和免疫抑制的基因,如Vegfa,Cd274和Arg1。

为了将在小鼠中的发现与人类CRC相关联,作者使用生存分析比较了具有不同水平C1QC+ TAM和SPP1+ TAM基因特征患者的生存率,发现低C1QC+ TAM、高SPP1 +TAM组合与CRC患者的预后更差相关(图26)。

这些发现表明,抗CSF1R治疗可能不足以耗尽所有具有促进肿瘤生长潜力的巨噬细胞,这一特性可能是其单药疗效差的原因。

类似的分析应用于抗CD40治疗则发现,抗CD40治疗能够激活cDC1细胞,CCL22等激活的基因特征与CRC患者的总体生存期呈正相关(图27),这可能部分解释了抗CD40激动剂治疗CRC的机制。

9.STARTRAC——分析T细胞的迁移、克隆扩增和发育转变

众所周知,T细胞在肿瘤免疫治疗中发挥重要作用。为进一步探索抗CD40激动剂治疗CRC的机制,作者基于TCRα和β链序列,应用STARTRAC算法分析抗CD40治疗后T细胞的迁移、克隆扩增和发育转变,以了解抗CD40激动剂治疗对肿瘤浸润性T细胞功能的影响。

结果显示,抗CD40激动剂治疗后,Ccl5+ Tem CD8+ T细胞具有比其他CD8+ T细胞亚群更高的迁移指数(图28)。进一步剖析Ccl5+ Tem亚群内的TCR克隆型表明,克隆扩增较高的细胞在肿瘤和肿瘤引流淋巴结之间表现出更多的TCR共享,表明这些细胞在抗CD40处理后具有更强的迁移能力(图29)。

同时,Ccl5+ Tem和Cxcr6+ Trm CD8+ T细胞之间的过渡指数在基线时显着高于CD8+ T细胞亚群中其他对的过渡指数,表明某些Cxcr6+ 肿瘤中的Trm细胞可能在某一过程中由浸润的Ccl5+ Tem细胞发育转变而来,这一过程在抗CD40治疗后得到了进一步增强(图30)。

这些数据表明,抗CD40治疗对肿瘤浸润性T细胞的扩增,迁移和发育转变具有独特影响,能够加强Ccl5+ Tem的迁移和克隆扩增能力,及其向Cxcr6+ Trm CD8+ T细胞转变的能力。

10.相关性分析——揭示细胞间存在相互作用

在研究中作者发现,Th1类细胞与成熟和未成熟的cDC1细胞均显示正相关,表明这两类细胞之间存在相互作用。在此基础上,结合该研究中发现的Bhlhe40 + Th1类细胞在抗CD40治疗后的占比以及特异性扩增、Bhlhe40 + CD4 + T细胞能够产生更多IFNγ,以及之前研究发现的表达IFNG的BHLHE40 + Th1样细胞富集于MSI CRC患者人群中且显示出对ICB治疗的良好反应等结果,作者认为抗CD40治疗导致增加的Bhlhe40 + Th1样细胞可能为在该模型中CD40激动剂治疗能够成功与抗PD1协同的机制提供了解释。

总的来说,该研究的思路是:

先通过单细胞转录组、免疫组测序等技术,对CRC患者的肿瘤微环境进行细胞分群、基因差异表达、细胞发育轨迹、细胞间相互作用等多水平、多维度的详细表征,发现了肿瘤浸润髓系细胞类群中两类特殊的细胞类群TAM和cDC可能在CRC的抗肿瘤T细胞应答、肿瘤发生等过程起调节作用。然后利用小鼠模型,将上述发现应用于对anti-CSF1R抑制剂和anti-CD40激动剂两种靶向髓系细胞的免疫治疗策略的潜在作用机理的解释中。

参考文献:

Lei Z. et al., Single-Cell Analyses Inform Mechanisms of Myeloid-Targeted Therapies in Colon Cancer.  Cell . 2020.

6. 游程编码源代码

这个...........楼上的诸位说的都是什么啊。今天刚好看到这个问题,把你的E-mail给我把,我有纯c的源码(RLC)。

算了,直接贴关键部分吧。这个有一点C++成分,很容易改的。
bool CompressRunLength(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen, int nBitsPerSample, void* nRuns, int nRunCount, int nRunSize);
bool DecompressRunLength(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen);

#define GetDWORD(buf,bit,mask) ((*(DWORD*)(((BYTE*)buf)+((bit)>>3)))>>((bit)&7)&(mask))
#define GetWORD(buf,bit,mask) ((*(WORD*)(((BYTE*)buf)+((bit)>>3)))>>((bit)&7)&(mask))

int GetBitCount(int n)
{
int nBitCount = 0;
while(n)
n >>= 1, nBitCount++;
return nBitCount;
}

int BinarySearch(void* pValue, int nVlaueSize, void* pArray, int nCount)
{
int nIndex, nResult, nStart = 0, nEnd = nCount-1;
while(nStart <= nEnd)
{
nIndex = (nEnd+nStart)/2;
if((nResult = memcmp((BYTE*)pArray+nIndex*nVlaueSize, pValue, nVlaueSize)) == 0)
return nIndex;
if(nResult > 0)
nEnd = nIndex-1;
else
nStart = nIndex+1;
}
return -1;
}

bool CompressRunLength(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen, int nBitsPerSample, void* nRuns, int nRunCount, int nRunSize)
{
pDes = (BYTE*)malloc(nSrcLen*2);
memset(pDes, 0, nSrcLen*2);

nDesLen = sizeof(DWORD);
*(DWORD*)pDes = nSrcLen; // save source length
*(pDes+nDesLen++) = nBitsPerSample; // save bits per sample
*(pDes+nDesLen++) = nRunCount; // save runs count
*(pDes+nDesLen++) = nRunSize; // save run bytes
memcpy(pDes+nDesLen, nRuns, nRunCount*nRunSize); // save runs
nDesLen += nRunCount*nRunSize;
nDesLen <<= 3; // bytes to bits
if(nRunCount == 0)
nRunCount = 256, nRunSize = 1, nRuns = NULL;

int nBitsPerTypeIndex = GetBitCount(nRunCount-1);
int nMaxRunLength = (1 << nBitsPerSample)-1, nRunLength, nRunIndex, nByte = 0;
// loop in the source buffer
while(nByte < nSrcLen)
if((nRuns && (nRunIndex = BinarySearch(pSrc+nByte, nRunSize, nRuns, nRunCount)) != -1 &&
memcmp(pSrc+nByte+nRunSize, (BYTE*)nRuns+nRunIndex*nRunSize, nRunSize) == 0) ||
(!nRuns && (nRunIndex = *(pSrc+nByte)) == *(pSrc+nByte+1)))
{ // set bit to 1 to indicate type found
*(pDes+(nDesLen>>3)) |= 1 << (nDesLen&7);
*(DWORD*)(pDes+(++nDesLen>>3)) |= nRunIndex << (nDesLen&7);
nDesLen += nBitsPerTypeIndex;
// skip the two repeated runs
nByte += nRunSize*2;
// get run length - 2 (without the two repeated runs)
nRunLength = 0;
while(nRunLength < nMaxRunLength && nByte < nSrcLen &&
((nRuns && memcmp(pSrc+nByte, (BYTE*)nRuns+nRunIndex*nRunSize, nRunSize) == 0) || (!nRuns && (BYTE)nRunIndex == *(pSrc+nByte))))
nRunLength++, nByte += nRunSize;
// save run length and increment destination length by bits per sample
*(DWORD*)(pDes+(nDesLen>>3)) |= nRunLength << (nDesLen&7);
nDesLen += nBitsPerSample;
}
else // one byte
*(WORD*)(pDes+(++nDesLen>>3)) |= *(pSrc+nByte++) << (nDesLen&7), nDesLen += 8;
nDesLen = (nDesLen+7)/8; // bits to bytes
pDes = (BYTE*)realloc(pDes, nDesLen);

return true;
}

bool DecompressRunLength(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen)
{
if(nSrcLen == 0)
return true;

// allocate destination buffer
nDesLen = *(DWORD*)pSrc;
pDes = (BYTE*)malloc(nDesLen);
memset(pDes, 0, nDesLen);

// compression information
int nSrcIndex = sizeof(DWORD);
int nBitsPerSample = *(pSrc+nSrcIndex++);
int nRunCount = *(pSrc+nSrcIndex++);
int nRunSize = *(pSrc+nSrcIndex++);
void* nRuns = pSrc+nSrcIndex;
nSrcIndex += nRunSize*nRunCount;
nSrcIndex <<= 3; // bytes to bits
if(nRunCount == 0)
nRunCount = 256, nRunSize = 1, nRuns = NULL;

int nBitsPerTypeIndex = GetBitCount(nRunCount-1);
int nMaxTypeIndex = (1 << nBitsPerTypeIndex)-1;
int nMaxRunLength = (1 << nBitsPerSample)-1;
int nDesIndex = 0, nRunLength, nRunIndex, nRun, nByte;

nSrcLen <<= 3; // bytes to bits
while(nSrcIndex < nSrcLen-8)
if((*(pSrc+(nSrcIndex>>3)) >> (nSrcIndex++&7)) & 1)
{
nRunIndex = GetDWORD(pSrc, nSrcIndex, nMaxTypeIndex), nSrcIndex += nBitsPerTypeIndex;
nRunLength = GetDWORD(pSrc, nSrcIndex, nMaxRunLength)+2, nSrcIndex += nBitsPerSample;
for(nRun = 0; nRun < nRunLength; nRun++)
for(nByte = 0; nByte < nRunSize; nByte++, nDesIndex += 8)
*(WORD*)(pDes+(nDesIndex>>3)) |= nRuns ? GetWORD(nRuns+nRunSize*nRunIndex, nByte<<3, 0xff) : (BYTE)nRunIndex;
}
else // one byte
*(WORD*)(pDes+(nDesIndex>>3)) |= GetWORD(pSrc, nSrcIndex, 0xff), nDesIndex += 8, nSrcIndex += 8;

return true;
}

7. 求32位MD5加密c语言源码

#include<stdio.h>
#include<string.h>
#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 RL(x, y) (((x) << (y)) | ((x) >> (32 - (y)))) //x向左循环移y位

#define PP(x) (x<<24)|((x<<8)&0xff0000)|((x>>8)&0xff00)|(x>>24) //将x高低位互换,例如PP(aabbccdd)=ddccbbaa

#define FF(a, b, c, d, x, s, ac) a = b + (RL((a + F(b,c,d) + x + ac),s))
#define GG(a, b, c, d, x, s, ac) a = b + (RL((a + G(b,c,d) + x + ac),s))
#define HH(a, b, c, d, x, s, ac) a = b + (RL((a + H(b,c,d) + x + ac),s))
#define II(a, b, c, d, x, s, ac) a = b + (RL((a + I(b,c,d) + x + ac),s))

unsigned A,B,C,D,a,b,c,d,i,len,flen[2],x[16]; //i临时变量,len文件长,flen[2]为64位二进制表示的文件初始长度
char filename[200]; //文件名
FILE *fp;

void md5(){ //MD5核心算法,供64轮

a=A,b=B,c=C,d=D;
/**//* Round 1 */
FF (a, b, c, d, x[ 0], 7, 0xd76aa478); /**//* 1 */
FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); /**//* 2 */
FF (c, d, a, b, x[ 2], 17, 0x242070db); /**//* 3 */
FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); /**//* 4 */
FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); /**//* 5 */
FF (d, a, b, c, x[ 5], 12, 0x4787c62a); /**//* 6 */
FF (c, d, a, b, x[ 6], 17, 0xa8304613); /**//* 7 */
FF (b, c, d, a, x[ 7], 22, 0xfd469501); /**//* 8 */
FF (a, b, c, d, x[ 8], 7, 0x698098d8); /**//* 9 */
FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); /**//* 10 */
FF (c, d, a, b, x[10], 17, 0xffff5bb1); /**//* 11 */
FF (b, c, d, a, x[11], 22, 0x895cd7be); /**//* 12 */
FF (a, b, c, d, x[12], 7, 0x6b901122); /**//* 13 */
FF (d, a, b, c, x[13], 12, 0xfd987193); /**//* 14 */
FF (c, d, a, b, x[14], 17, 0xa679438e); /**//* 15 */
FF (b, c, d, a, x[15], 22, 0x49b40821); /**//* 16 */

/**//* Round 2 */
GG (a, b, c, d, x[ 1], 5, 0xf61e2562); /**//* 17 */
GG (d, a, b, c, x[ 6], 9, 0xc040b340); /**//* 18 */
GG (c, d, a, b, x[11], 14, 0x265e5a51); /**//* 19 */
GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /**//* 20 */
GG (a, b, c, d, x[ 5], 5, 0xd62f105d); /**//* 21 */
GG (d, a, b, c, x[10], 9, 0x02441453); /**//* 22 */
GG (c, d, a, b, x[15], 14, 0xd8a1e681); /**//* 23 */
GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /**//* 24 */
GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); /**//* 25 */
GG (d, a, b, c, x[14], 9, 0xc33707d6); /**//* 26 */
GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); /**//* 27 */
GG (b, c, d, a, x[ 8], 20, 0x455a14ed); /**//* 28 */
GG (a, b, c, d, x[13], 5, 0xa9e3e905); /**//* 29 */
GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); /**//* 30 */
GG (c, d, a, b, x[ 7], 14, 0x676f02d9); /**//* 31 */
GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); /**//* 32 */

/**//* Round 3 */
HH (a, b, c, d, x[ 5], 4, 0xfffa3942); /**//* 33 */
HH (d, a, b, c, x[ 8], 11, 0x8771f681); /**//* 34 */
HH (c, d, a, b, x[11], 16, 0x6d9d6122); /**//* 35 */
HH (b, c, d, a, x[14], 23, 0xfde5380c); /**//* 36 */
HH (a, b, c, d, x[ 1], 4, 0xa4beea44); /**//* 37 */
HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); /**//* 38 */
HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); /**//* 39 */
HH (b, c, d, a, x[10], 23, 0xbebfbc70); /**//* 40 */
HH (a, b, c, d, x[13], 4, 0x289b7ec6); /**//* 41 */
HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); /**//* 42 */
HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); /**//* 43 */
HH (b, c, d, a, x[ 6], 23, 0x04881d05); /**//* 44 */
HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); /**//* 45 */
HH (d, a, b, c, x[12], 11, 0xe6db99e5); /**//* 46 */
HH (c, d, a, b, x[15], 16, 0x1fa27cf8); /**//* 47 */
HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); /**//* 48 */

/**//* Round 4 */
II (a, b, c, d, x[ 0], 6, 0xf4292244); /**//* 49 */
II (d, a, b, c, x[ 7], 10, 0x432aff97); /**//* 50 */
II (c, d, a, b, x[14], 15, 0xab9423a7); /**//* 51 */
II (b, c, d, a, x[ 5], 21, 0xfc93a039); /**//* 52 */
II (a, b, c, d, x[12], 6, 0x655b59c3); /**//* 53 */
II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); /**//* 54 */
II (c, d, a, b, x[10], 15, 0xffeff47d); /**//* 55 */
II (b, c, d, a, x[ 1], 21, 0x85845dd1); /**//* 56 */
II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); /**//* 57 */
II (d, a, b, c, x[15], 10, 0xfe2ce6e0); /**//* 58 */
II (c, d, a, b, x[ 6], 15, 0xa3014314); /**//* 59 */
II (b, c, d, a, x[13], 21, 0x4e0811a1); /**//* 60 */
II (a, b, c, d, x[ 4], 6, 0xf7537e82); /**//* 61 */
II (d, a, b, c, x[11], 10, 0xbd3af235); /**//* 62 */
II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /**//* 63 */
II (b, c, d, a, x[ 9], 21, 0xeb86d391); /**//* 64 */

A += a;
B += b;
C += c;
D += d;

}

main(){
while(1){
printf("Input file:");
gets(filename); //用get函数,避免scanf以空格分割数据,
if (filename[0]==34) filename[strlen(filename)-1]=0,strcpy(filename,filename+1); //支持文件拖曳,但会多出双引号,这里是处理多余的双引号
if (!strcmp(filename,"exit")) exit(0); //输入exit退出
if (!(fp=fopen(filename,"rb"))) {printf("Can not open this file!\n");continue;} //以二进制打开文件
fseek(fp, 0, SEEK_END); //文件指针转到文件末尾
if((len=ftell(fp))==-1) {printf("Sorry! Can not calculate files which larger than 2 GB!\n");fclose(fp);continue;} //ftell函数返回long,最大为2GB,超出返回-1
rewind(fp); //文件指针复位到文件头
A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476; //初始化链接变量
flen[1]=len/0x20000000; //flen单位是bit
flen[0]=(len%0x20000000)*8;
memset(x,0,64); //初始化x数组为0
fread(&x,4,16,fp); //以4字节为一组,读取16组数据
for(i=0;i<len/64;i++){ //循环运算直至文件结束
md5();
memset(x,0,64);
fread(&x,4,16,fp);
}
((char*)x)[len%64]=128; //文件结束补1,补0操作,128二进制即10000000
if(len%64>55) md5(),memset(x,0,64);
memcpy(x+14,flen,8); //文件末尾加入原文件的bit长度
md5();
fclose(fp);
printf("MD5 Code:%08x%08x%08x%08x\n",PP(A),PP(B),PP(C),PP(D)); //高低位逆反输出
}
}

阅读全文

与HMPP算法源码相关的资料

热点内容
不能修改的pdf 浏览:739
同城公众源码 浏览:475
一个服务器2个端口怎么映射 浏览:283
java字符串ascii码 浏览:62
台湾云服务器怎么租服务器 浏览:462
旅游手机网站源码 浏览:317
android关联表 浏览:930
安卓导航无声音怎么维修 浏览:322
app怎么装视频 浏览:424
安卓系统下的软件怎么移到桌面 浏览:81
windows拷贝到linux 浏览:757
mdr软件解压和别人不一样 浏览:889
单片机串行通信有什么好处 浏览:325
游戏开发程序员书籍 浏览:849
pdf中图片修改 浏览:275
汇编编译后 浏览:480
php和java整合 浏览:835
js中执行php代码 浏览:447
国产单片机厂商 浏览:63
苹果手机怎么设置不更新app软件 浏览:289