精华内容
下载资源
问答
  • OGL选择和反馈模式

    千次阅读 2016-10-16 09:54:19
    选择和反馈模式基本知识 渲染物体时候除了直接在屏幕上显示,还可以启用选择或反馈模式绘制物体但是不显示,得到一些绘图信息。 选择模式只是表明那些物体和视景体相交,用挑选功能可以实现用户和绘制图元的交互。 ...

    选择和反馈模式基本知识

    渲染物体时候除了直接在屏幕上显示,还可以启用选择或反馈模式绘制物体但是不显示,得到一些绘图信息。
    选择模式只是表明那些物体和视景体相交,用挑选功能可以实现用户和绘制图元的交互。
    反馈模式是返回绘图信息,用于绘图仪的设备中。
    选择和反馈模式下,绘图信息都是直接返回给应用程序而不是像渲染模式一样将信息发送到帧缓存,所以在选择和反馈模式下屏幕冻结不会进行绘图,颜色,深度,模板,累积缓存区的数据不会发生变化反馈模式和选择模式下的图元信息,都是没有经过任何片段测试返回的,所以没有经过测试的信息也会从选择或反馈信息中得到。
    且非选择和反馈模式下,与他们相关的函数不会起作用。
    拾取的判断,是将点击射线来自屏幕点击点的(clickPoint.x, clickPoint.y, znear), (clickPoint.x, clickPoint.y, zfar),转换到世界或视图坐标系得到射线(不是原点到鼠标的射线);然后与视图内的可拾取物体的包围盒做相交检测判断。

    选择模式步骤

    // 1.使用glSelectBuffer函数指定用于返回点击记录的数组。 和视景体相交的图元会导致一次选择点击,如果出现一次点击也会把点击记录写入。每条点击记录包含四项,当点击发生时候名字堆栈中的名称数量,当前点击与视景体相交的图元的所有顶点的最小和最大窗口z值会乘以2^23 - 1,点击发生时名字堆栈的内容,从底部的元素开始。
    glSelectBuffer (BUFSIZE, selectBuf);
    // 2.用glRenderMode指定GL_SELECT,进入选择模式;默认是GL_RENDER_MODE,反馈模式是GL_FEEDBACK
    (void) glRenderMode (GL_SELECT);
    // 3.对名字进行初始化
    glInitNames();
    glPushName(0);//避免glLoadName出错

    // 4.定义用于选择的视景体,这里和绘制物体的视景体一样;交替用于绘制图元的函数和操纵名字栈的函数,绘制物体会使用最近的名字,。
    //glLoadName后进行了drawcall调用,因此尽管名字堆栈只有一个元素,但是drawcall使得名字和物体产生的联系,一个元素足够了。

    选择模式下得到和视景体相交的图元点击记录

    #include <GL/glut.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    /* draw a triangle with vertices at (x1, y1), (x2, y2) 
     * and (x3, y3) at z units away from the origin.
     */
    void drawTriangle (GLfloat x1, GLfloat y1, GLfloat x2, 
        GLfloat y2, GLfloat x3, GLfloat y3, GLfloat z)
    {
       glBegin (GL_TRIANGLES);
       glVertex3f (x1, y1, z);
       glVertex3f (x2, y2, z);
       glVertex3f (x3, y3, z);
       glEnd ();
    }
    
    /* draw a rectangular box with these outer x, y, and z values */
    void drawViewVolume (GLfloat x1, GLfloat x2, GLfloat y1, 
                         GLfloat y2, GLfloat z1, GLfloat z2)
    {
       glColor3f (1.0, 1.0, 1.0);
       glBegin (GL_LINE_LOOP);
       glVertex3f (x1, y1, -z1);
       glVertex3f (x2, y1, -z1);
       glVertex3f (x2, y2, -z1);
       glVertex3f (x1, y2, -z1);
       glEnd ();
    
       glBegin (GL_LINE_LOOP);
       glVertex3f (x1, y1, -z2);
       glVertex3f (x2, y1, -z2);
       glVertex3f (x2, y2, -z2);
       glVertex3f (x1, y2, -z2);
       glEnd ();
    
       glBegin (GL_LINES);	/*  4 lines	*/
       glVertex3f (x1, y1, -z1);
       glVertex3f (x1, y1, -z2);
       glVertex3f (x1, y2, -z1);
       glVertex3f (x1, y2, -z2);
       glVertex3f (x2, y1, -z1);
       glVertex3f (x2, y1, -z2);
       glVertex3f (x2, y2, -z1);
       glVertex3f (x2, y2, -z2);
       glEnd ();
    }
    
    /* drawScene draws 4 triangles and a wire frame
     * which represents the viewing volume.
     */
    void drawScene (void)
    {
       glMatrixMode (GL_PROJECTION);
       glLoadIdentity ();
       gluPerspective (40.0, 4.0/3.0, 1.0, 100.0);
    
       glMatrixMode (GL_MODELVIEW);
       glLoadIdentity ();
       gluLookAt (7.5, 7.5, 12.5, 2.5, 2.5, -5.0, 0.0, 1.0, 0.0);
       glColor3f (0.0, 1.0, 0.0);	/*  green triangle	*/
       drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -5.0);
       glColor3f (1.0, 0.0, 0.0);	/*  red triangle	*/
       drawTriangle (2.0, 7.0, 3.0, 7.0, 2.5, 8.0, -5.0);
       glColor3f (1.0, 1.0, 0.0);	/*  yellow triangles	*/
       drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -1.0);
       drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -9.0);
       drawViewVolume (0.0, 5.0, 0.0, 5.0, 0.0, 10.0);
    }
    
    /* processHits prints out the contents of the selection array
     */
    void processHits (GLint hits, GLuint buffer[])
    {
       unsigned int i, j;
       GLuint names, *ptr;
    
       printf ("hits = %d\n", hits);
       ptr = (GLuint *) buffer;
       for (i = 0; i < hits; i++) {	/*  for each hit  */
          names = *ptr;
          printf (" number of names for hit = %d\n", names); ptr++;
          printf("  z1 is %g;", (float) *ptr/0x7fffffff); ptr++;
          printf(" z2 is %g\n", (float) *ptr/0x7fffffff); ptr++;
          printf ("   the name is ");
          for (j = 0; j < names; j++) {	/*  for each name */
             printf ("%d ", *ptr); ptr++;
          }
          printf ("\n");
       }
    }
    
    /* selectObjects "draws" the triangles in selection mode, 
     * assigning names for the triangles.  Note that the third
     * and fourth triangles share one name, so that if either 
     * or both triangles intersects the viewing/clipping volume, 
     * only one hit will be registered.
     */
    #define BUFSIZE 512
    
    void selectObjects(void)
    {
       GLuint selectBuf[BUFSIZE];
       GLint hits;
       // 1.使用glSelectBuffer函数指定用于返回点击记录的数组。
       glSelectBuffer (BUFSIZE, selectBuf);
       // 2.用glRenderMode指定GL_SELECT,进入选择模式;默认是GL_RENDER_MODE,反馈模式是GL_FEEDBACK
       (void) glRenderMode (GL_SELECT);
       // 3.对名字进行初始化
       glInitNames();
       glPushName(0);//避免glLoadName出错 
    
       // 4.定义用于选择的视景体,这里和绘制物体的视景体一样;交替用于绘制图元的函数和操纵名字栈的函数,绘制物体会使用最近的名字。
       glPushMatrix ();
       glMatrixMode (GL_PROJECTION);
       glLoadIdentity ();
       glOrtho (0.0, 5.0, 0.0, 5.0, 0.0, 10.0);
       glMatrixMode (GL_MODELVIEW);
       glLoadIdentity ();
       glLoadName(1);
       drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -5.0);
       //load后进行了drawcall调用,因此尽管名字堆栈只有一个元素,但是drawcall使得名字和物体产生的联系,一个元素足够了。
       glLoadName(2);
       drawTriangle (2.0, 7.0, 3.0, 7.0, 2.5, 8.0, -5.0);
       glLoadName(3);
       drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -1.0);
       drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -9.0);
       glPopMatrix ();
       glFlush ();
    
       hits = glRenderMode (GL_RENDER);
       processHits (hits, selectBuf);
    } 
    
    void init (void) 
    {
       glEnable(GL_DEPTH_TEST);
       glShadeModel(GL_FLAT);
    }
    
    void display(void)
    {
       glClearColor (0.0, 0.0, 0.0, 0.0);
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       drawScene ();
       selectObjects ();
       glFlush();
    }
    
    void keyboard(unsigned char key, int x, int y)
    {
       switch (key) {
          case 27:
             exit(0);
             break;
       }
    }
    
    /*  Main Loop  */
    int main(int argc, char** argv)
    {
       glutInit(&argc, argv);
       glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
       glutInitWindowSize (200, 200);
       glutInitWindowPosition (100, 100);
       glutCreateWindow (argv[0]);
       init();
       glutDisplayFunc(display);
       glutKeyboardFunc(keyboard);
       glutMainLoop();
       return 0; 
    }

    挑选步骤:

    1.使用了特殊的挑选矩阵 gluPickMatrix x投影矩阵gluOrtho2D把绘图限制在一个视口的小区域内。
    2.在光标处绘制的物体,就会导致一次点击;因此挑选一般是用于判断哪些物体是在靠近光标的位置绘制的。和视景体相交的图元会导致一次选择点击,通过drawSquares后在glSelectBuffer数组里面就可以捕获到。
    3.根据selectBuf选择的点击明,刚好是行列名来改变board颜色,并在GL_RENDER下glutPostRedisplay绘制变化的图元。
    OGL的挑选模式是,根据传入的鼠标位置,构建挑选矩阵,然后全部物体用选择模式提交一次渲染得到点击的名字列表,根据名字列表来索引到物体,修改物体的相应属性,再次绘制得到交互结果。

    DX是直接场景管理,将可交互物体的对象名和摄像机空间中的包围盒建立一个集合,且将这些集合用8叉树空间的模式来进行管理(剔除不在视景体里面的物体),在摄像机空间,点击射线来自屏幕点击点的(clickPoint.x, clickPoint.y, znear), (clickPoint.x, clickPoint.y, zfar),将射线转换到视图坐标系中的射线,当鼠标点击后如果是2D正交投影的直接转换到世界空间坐标系进行射线和平面交叉检查;如果是3D透视投影的,通过遍历集合中的物体和射线的相交检查。显然类似DX中的拾取技术是更加有效的。

    挑选模式下的实例和解释:

    #include <GL/glut.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int board[3][3];   /*  amount of color for each square	*/
    
    /*  Clear color value for every square on the board   */
    void init(void)
    {
       int i, j;
       for (i = 0; i < 3; i++) 
          for (j = 0; j < 3; j ++)
             board[i][j] = 0;
       glClearColor (0.0, 0.0, 0.0, 0.0);
    }
    
    /*  The nine squares are drawn.  In selection mode, each 
     *  square is given two names:  one for the row and the 
     *  other for the column on the grid.  The color of each 
     *  square is determined by its position on the grid, and 
     *  the value in the board[][] array.
     */
    void drawSquares(GLenum mode)
    {
       GLuint i, j;
       for (i = 0; i < 3; i++) {
    	   if (mode == GL_SELECT)
    		   glLoadName(i);// 名字1
    	  for (j = 0; j < 3; j++) {
             if (mode == GL_SELECT)
                glPushName (j);// 名字2,用两个名字来代表一个图元。
             glColor3f ((GLfloat) i/3.0, (GLfloat) j/3.0, 
                        (GLfloat) board[i][j]/3.0);
             glRecti (i, j, i+1, j+1);
             if (mode == GL_SELECT)
                glPopName (); // 会弹出来,每次名字堆栈中只有两个名字。
          }
       }
    }
    
    /*  processHits prints out the contents of the 
     *  selection array.
     */
    void processHits (GLint hits, GLuint buffer[])
    {
       unsigned int i, j;
       GLuint ii, jj, names, *ptr;
    
       printf ("hits = %d\n", hits);
       ptr = (GLuint *) buffer;
       for (i = 0; i < hits; i++) {	/*  for each hit  */
          names = *ptr;
          printf (" number of names for this hit = %d\n", names); ptr++;
          printf("  z1 is %g;", (float) *ptr/0x7fffffff); ptr++;
          printf(" z2 is %g\n", (float) *ptr/0x7fffffff); ptr++;
          printf ("   names are ");
          for (j = 0; j < names; j++) { /*  for each name */
             printf ("%d ", *ptr);
             if (j == 0)  /*  set row and column  */
                ii = *ptr;
             else if (j == 1)
                jj = *ptr;
             ptr++;
          }
          printf ("\n");
          board[ii][jj] = (board[ii][jj] + 1) % 3;
       }
    }
    
    /*  pickSquares() sets up selection mode, name stack, 
     *  and projection matrix for picking.  Then the 
     *  objects are drawn.
     */
    #define BUFSIZE 512
    
    void pickSquares(int button, int state, int x, int y)
    {
       GLuint selectBuf[BUFSIZE];
       GLint hits;
       GLint viewport[4];
    
       if (button != GLUT_LEFT_BUTTON || state != GLUT_DOWN)
          return;
    
       glGetIntegerv (GL_VIEWPORT, viewport);
    
       glSelectBuffer (BUFSIZE, selectBuf);
       (void) glRenderMode (GL_SELECT);
    
       glInitNames();
       glPushName(0);
    
       glMatrixMode (GL_PROJECTION);
       glPushMatrix ();
       glLoadIdentity ();
    /*  create 5x5 pixel picking region near cursor location	*/
       // 1.使用了特殊的挑选矩阵x投影矩阵gluOrtho2D把绘图限制在一个视口的小区域内。
        gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y),
    				   5.0, 5.0, viewport);
       gluOrtho2D (0.0, 3.0, 0.0, 3.0);
       // 2.在光标处绘制的物体,就会导致一次点击;因此挑选一般是用于判断哪些物体是在靠近光标的位置绘制的。
       // 和视景体相交的图元会导致一次选择点击,通过drawSquares后在glSelectBuffer数组里面就可以捕获到。
       drawSquares (GL_SELECT);
    
       glMatrixMode (GL_PROJECTION);
       glPopMatrix ();
       glFlush ();
    
       hits = glRenderMode(GL_RENDER);
       //3.根据selectBuf选择的点击明,刚好是行列名来改变board颜色,并在GL_RENDER下glutPostRedisplay绘制变化的图元。
       processHits(hits, selectBuf);
       glutPostRedisplay();
    } 
    
    void display(void)
    {
       glClear(GL_COLOR_BUFFER_BIT);
       drawSquares (GL_RENDER);
       glFlush();
    }
    
    void reshape(int w, int h)
    {
       glViewport(0, 0, w, h);
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
       gluOrtho2D (0.0, 3.0, 0.0, 3.0);
       glMatrixMode(GL_MODELVIEW);
       glLoadIdentity();
    }
    
    void keyboard(unsigned char key, int x, int y)
    {
       switch (key) {
          case 27:
             exit(0);
             break;
       }
    }
    
    /* Main Loop */
    int main(int argc, char** argv)
    {
       glutInit(&argc, argv);
       glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
       glutInitWindowSize (100, 100);
       glutInitWindowPosition (100, 100);
       glutCreateWindow (argv[0]);
       init ();
       glutReshapeFunc (reshape);
       glutDisplayFunc(display); 
       glutMouseFunc (pickSquares);
       glutKeyboardFunc (keyboard);
       glutMainLoop();
       return 0; 
    }


    如果多个物体在选中,可以在挑选的点击记录里面深度值最低的值

    #include <GL/glut.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    void init(void)
    {
       glClearColor(0.0, 0.0, 0.0, 0.0);
       glEnable(GL_DEPTH_TEST);
       glShadeModel(GL_FLAT);
       glDepthRange(0.0, 1.0);  /* The default z mapping */
    }
    
    /* The three rectangles are drawn.  In selection mode, 
     * each rectangle is given the same name.  Note that 
     * each rectangle is drawn with a different z value.
     */
    void drawRects(GLenum mode)
    {
       if (mode == GL_SELECT)
          glLoadName(1);
       glBegin(GL_QUADS);
       glColor3f(1.0, 1.0, 0.0);
       glVertex3i(2, 0, 0);
       glVertex3i(2, 6, 0);
       glVertex3i(6, 6, 0);
       glVertex3i(6, 0, 0);
       glEnd();
       if (mode == GL_SELECT)
          glLoadName(2);
       glBegin(GL_QUADS);
       glColor3f(0.0, 1.0, 1.0);
       glVertex3i(3, 2, -1);
       glVertex3i(3, 8, -1);
       glVertex3i(8, 8, -1);
       glVertex3i(8, 2, -1);
       glEnd();
       if (mode == GL_SELECT)
          glLoadName(3);
       glBegin(GL_QUADS);
       glColor3f(1.0, 0.0, 1.0);
       glVertex3i(0, 2, -2);
       glVertex3i(0, 7, -2);
       glVertex3i(5, 7, -2);
       glVertex3i(5, 2, -2);
       glEnd();
    }
    
    /*  processHits() prints out the contents of the 
     *  selection array.
     */
    // 自定义的深度挑选记录
    typedef struct tagNameRecord{
    	GLuint objNum;
    	GLuint *objName;
    	GLfloat zValue;
    }NameRecord;
    
    void processHits(GLint hits, GLuint buffer[])
    {
       unsigned int i, j;
       GLuint names, *ptr;
    
       NameRecord nearName;
       memset(&nearName, 0, sizeof(NameRecord));
       nearName.zValue = 100;
       printf("hits = %d\n", hits);
       ptr = (GLuint *) buffer;
       for (i = 0; i < hits; i++) {  /* for each hit  */
          names = *ptr;
          printf(" number of names for hit = %d\n", names); ptr++;
    	  float z1Value = (float)*ptr / 0x7fffffff;
          printf("  z1 is %g;", (float) *ptr/0x7fffffff); ptr++;
    	  float z2Value = (float)*ptr / 0x7fffffff;
          printf(" z2 is %g\n", (float) *ptr/0x7fffffff); ptr++;
          printf("   the name is ");
    	  if (nearName.zValue > z1Value)
    	  {
    		  nearName.zValue = z1Value;
    		  nearName.objName = ptr;
    		  nearName.objNum = names;
    	  }
          for (j = 0; j < names; j++) {  /* for each name */
             printf("%d ", *ptr); ptr++;
          }
          printf("\n");
       }
       // 获取z值最近的物体的名称。
       printf("proce                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         ssHits nearName.zValue object name:\n");
       for (j = 0; j < nearName.objNum; j++) {  /* for each name */
    	   printf("%d ", *nearName.objName); nearName.objName++;
       }
       printf("\n");
    }
    
    /*  pickRects() sets up selection mode, name stack, 
     *  and projection matrix for picking.  Then the objects 
     *  are drawn.
     */
    #define BUFSIZE 512
    
    void pickRects(int button, int state, int x, int y)
    {
       GLuint selectBuf[BUFSIZE];
       GLint hits;
       GLint viewport[4];
    
       if (button != GLUT_LEFT_BUTTON || state != GLUT_DOWN)
          return;
    
       glGetIntegerv(GL_VIEWPORT, viewport);
    
       glSelectBuffer(BUFSIZE, selectBuf);
       (void) glRenderMode(GL_SELECT);
    
       glInitNames();
       glPushName(0);
    
       glMatrixMode(GL_PROJECTION);
       glPushMatrix();
       glLoadIdentity();
    /*  create 5x5 pixel picking region near cursor location */
       gluPickMatrix((GLdouble) x, (GLdouble) (viewport[3] - y),
                     5.0, 5.0, viewport);
       glOrtho(0.0, 8.0, 0.0, 8.0, -0.5, 2.5);
       drawRects(GL_SELECT);
       glPopMatrix();
       glFlush();
    
       hits = glRenderMode(GL_RENDER);
       processHits(hits, selectBuf);
    }
    
    void display(void)
    {
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       drawRects(GL_RENDER);
       glFlush();
    }
    
    void reshape(int w, int h)
    {
       glViewport(0, 0, (GLsizei) w, (GLsizei) h);
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
       glOrtho(0.0, 8.0, 0.0, 8.0, -0.5, 2.5);
       glMatrixMode(GL_MODELVIEW);
       glLoadIdentity();
    }
    
    void keyboard(unsigned char key, int x, int y)
    {
       switch (key) {
          case 27:
             exit(0);
             break;
       }
    }
    
    /*  Main Loop
     */
    int main(int argc, char **argv)
    {
       glutInit(&argc, argv);
       glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
       glutInitWindowSize (200, 200);
       glutInitWindowPosition (100, 100);
       glutCreateWindow(argv[0]);
       init();
       glutReshapeFunc(reshape);
       glutDisplayFunc(display);
       glutMouseFunc(pickRects);
       glutKeyboardFunc(keyboard);
       glutMainLoop();
       return 0; 
    }

    反馈模式

    反馈模式是在光栅化后,返回的顶点或颜色,纹理信息都是光栅化窗口坐标系中的坐标。反馈模式和选择模式下的图元信息,都是没有经过任何片段测试的,所以没有经过测试的信息也会从选择或反馈信息中得到。
    步骤:
    1.声明反馈模式的数组,数组的类型GL_3D顶点,GL_3D_COLOR包括了顶点和颜色,GL_3D_COLOR_TEXTURE顶点颜色和纹理.
    2.设置为反馈渲染模式,GL_FEEDBACK。
    3.绘制物体,glPassThrough()插入标记,区分一些图形裁剪剔除。
    4.返回的顶点数量,返回的结构包括type1,valueseq1,...typen, valueseqn。

    反馈模式代码:

    #include <GL/glut.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    /*  Initialize lighting.
     */
    void init(void)
    {
       glEnable(GL_LIGHTING);
       glEnable(GL_LIGHT0);
    }
    
    /* Draw a few lines and two points, one of which will 
     * be clipped.  If in feedback mode, a passthrough token 
     * is issued between the each primitive.
     */
    void drawGeometry (GLenum mode)
    {
       glBegin(GL_LINE_LOOP);// GL_LINE_STRIP模式会产生2条线段,Loop是3条
       glNormal3f (0.0, 0.0, 1.0);
       glVertex3f (40.0, 30.0, 0.0);
       glVertex3f (60.0, 60.0, 0.0);
       glVertex3f (70.0, 40.0, 0.0);
       glEnd ();
       if (mode == GL_FEEDBACK)
          glPassThrough (1.0);
       glBegin (GL_POINTS);
       glVertex3f (-100.0, -100.0, -100.0);  /*  will be clipped  */
       glEnd ();
       if (mode == GL_FEEDBACK)
          glPassThrough (2.0);
       glBegin (GL_POINTS);
       glNormal3f (0.0, 0.0, 1.0);
       glVertex3f (50.0, 50.0, 0.0);
       glEnd ();
    }
    
    /* Write contents of one vertex to stdout.	*/
    void print3DcolorVertex (GLint size, GLint *count, 
                             GLfloat *buffer)
    {
       int i;
    
       printf ("  ");
       for (i = 0; i < 7; i++) {
          printf ("%4.2f ", buffer[size-(*count)]);
          *count = *count - 1;
       }
       printf ("\n");
    }
    
    /*  Write contents of entire buffer.  (Parse tokens!)	*/
    void printBuffer(GLint size, GLfloat *buffer)
    {
       GLint count;
       GLfloat token;
    
       count = size;
       while (count) {
          token = buffer[size-count]; count--;
          if (token == GL_PASS_THROUGH_TOKEN) {
             printf ("GL_PASS_THROUGH_TOKEN\n");
             printf ("  %4.2f\n", buffer[size-count]);
             count--;
          }
          else if (token == GL_POINT_TOKEN) {
             printf ("GL_POINT_TOKEN\n");
             print3DcolorVertex (size, &count, buffer);
          }
          else if (token == GL_LINE_TOKEN) {
             printf ("GL_LINE_TOKEN\n");
             print3DcolorVertex (size, &count, buffer);
             print3DcolorVertex (size, &count, buffer);
          }
          else if (token == GL_LINE_RESET_TOKEN) {
             printf ("GL_LINE_RESET_TOKEN\n");
             print3DcolorVertex (size, &count, buffer);
             print3DcolorVertex (size, &count, buffer);
          }
       }
    }
    
    void display(void)
    {
       GLfloat feedBuffer[1024];
       GLint size;
    
       glMatrixMode (GL_PROJECTION);
       glLoadIdentity ();
       glOrtho (0.0, 100.0, 0.0, 100.0, 0.0, 1.0);
    
       glClearColor (0.0, 0.0, 0.0, 0.0);
       glClear(GL_COLOR_BUFFER_BIT);
       drawGeometry (GL_RENDER);
    
       // 1.声明反馈模式的数组,数组的类型GL_3D顶点,GL_3D_COLOR包括了顶点和颜色,GL_3D_COLOR_TEXTURE顶点颜色和纹理.
       glFeedbackBuffer (1024, GL_3D_COLOR, feedBuffer);
       // 2.设置为反馈渲染模式,GL_FEEDBACK
       (void) glRenderMode (GL_FEEDBACK);
       // 3.绘制物体,glPassThrough()插入标记,区分一些图形裁剪剔除
       drawGeometry (GL_FEEDBACK);
    
       // 4.返回的顶点数量,返回的结构包括type1,valueseq1,...typen, valueseqn。
       size = glRenderMode (GL_RENDER);
       printBuffer (size, feedBuffer);
    }
    
    void keyboard(unsigned char key, int x, int y)
    {
       switch (key) {
          case 27:
             exit(0);
             break;
       }
    }
    
    /*  Main Loop  */
    int main(int argc, char** argv)
    {
       glutInit(&argc, argv);
       glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
       glutInitWindowSize (100, 100);
       glutInitWindowPosition (100, 100);
       glutCreateWindow(argv[0]);
       init();
       glutDisplayFunc(display);
       glutKeyboardFunc (keyboard);
       glutMainLoop();
       return 0; 
    }



    展开全文
  • 今天密码学老师布置的实验是用AES密码通过密文反馈模式加密文件,AES密码我在别的大佬的博客上借用了一下https://blog.csdn.net/lisonglisonglisong/article/details/41909813 #include <iostream> #include...

    今天密码学老师布置的实验是用AES密码通过密文反馈模式加密文件,AES密码我在别的大佬的博客上借用了一下https://blog.csdn.net/lisonglisonglisong/article/details/41909813

    #include <iostream>
    #include <bitset>
    #include <string>
    #include <fstream>
    #include <cstdlib>
    using namespace std;
    typedef bitset<8> byte;
    typedef bitset<32> word;
    typedef struct {
    	char name;
    	byte value;
    }HEX;
    byte table[26] = {0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,
    0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A};
    const int Nr = 10;  // AES-128需要 10 轮加密
    const int Nk = 4;   // Nk 表示输入密钥的 word 个数
    
    byte S_Box[16][16] = {
    	{0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76},
    	{0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0},
    	{0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15},
    	{0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75},
    	{0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84},
    	{0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF},
    	{0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8},
    	{0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2},
    	{0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73},
    	{0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB},
    	{0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79},
    	{0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08},
    	{0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A},
    	{0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E},
    	{0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF},
    	{0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16}
    };
    
    byte Inv_S_Box[16][16] = {
    	{0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB},
    	{0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB},
    	{0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E},
    	{0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25},
    	{0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92},
    	{0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84},
    	{0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06},
    	{0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B},
    	{0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73},
    	{0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E},
    	{0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B},
    	{0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4},
    	{0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F},
    	{0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF},
    	{0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61},
    	{0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D}
    };
    
    // 轮常数,密钥扩展中用到。(AES-128只需要10轮)
    word Rcon[10] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
    				 0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000 };
    
    /**********************************************************************/
    /*                                                                    */
    /*                              AES算法实现                           */
    /*                                                                    */
    /**********************************************************************/
    
    /******************************下面是加密的变换函数**********************/
    /**
     *  S盒变换 - 前4位为行号,后4位为列号
     */
    void SubBytes(byte mtx[4 * 4])
    {
    	for (int i = 0; i < 16; ++i)
    	{
    		int row = mtx[i][7] * 8 + mtx[i][6] * 4 + mtx[i][5] * 2 + mtx[i][4];
    		int col = mtx[i][3] * 8 + mtx[i][2] * 4 + mtx[i][1] * 2 + mtx[i][0];
    		mtx[i] = S_Box[row][col];
    	}
    }
    
    /**
     *  行变换 - 按字节循环移位
     */
    void ShiftRows(byte mtx[4 * 4])
    {
    	// 第二行循环左移一位
    	byte temp = mtx[4];
    	for (int i = 0; i < 3; ++i)
    		mtx[i + 4] = mtx[i + 5];
    	mtx[7] = temp;
    	// 第三行循环左移两位
    	for (int i = 0; i < 2; ++i)
    	{
    		temp = mtx[i + 8];
    		mtx[i + 8] = mtx[i + 10];
    		mtx[i + 10] = temp;
    	}
    	// 第四行循环左移三位
    	temp = mtx[15];
    	for (int i = 3; i > 0; --i)
    		mtx[i + 12] = mtx[i + 11];
    	mtx[12] = temp;
    }
    
    /**
     *  有限域上的乘法 GF(2^8)
     */
    byte GFMul(byte a, byte b) {
    	byte p = 0;
    	byte hi_bit_set;
    	for (int counter = 0; counter < 8; counter++) {
    		if ((b & byte(1)) != 0) {
    			p ^= a;
    		}
    		hi_bit_set = (byte)(a & byte(0x80));
    		a <<= 1;
    		if (hi_bit_set != 0) {
    			a ^= 0x1b; /* x^8 + x^4 + x^3 + x + 1 */
    		}
    		b >>= 1;
    	}
    	return p;
    }
    
    /**
     *  列变换
     */
    void MixColumns(byte mtx[4 * 4])
    {
    	byte arr[4];
    	for (int i = 0; i < 4; ++i)
    	{
    		for (int j = 0; j < 4; ++j)
    			arr[j] = mtx[i + j * 4];
    
    		mtx[i] = GFMul(0x02, arr[0]) ^ GFMul(0x03, arr[1]) ^ arr[2] ^ arr[3];
    		mtx[i + 4] = arr[0] ^ GFMul(0x02, arr[1]) ^ GFMul(0x03, arr[2]) ^ arr[3];
    		mtx[i + 8] = arr[0] ^ arr[1] ^ GFMul(0x02, arr[2]) ^ GFMul(0x03, arr[3]);
    		mtx[i + 12] = GFMul(0x03, arr[0]) ^ arr[1] ^ arr[2] ^ GFMul(0x02, arr[3]);
    	}
    }
    
    /**
     *  轮密钥加变换 - 将每一列与扩展密钥进行异或
     */
    void AddRoundKey(byte mtx[4 * 4], word k[4])
    {
    	for (int i = 0; i < 4; ++i)
    	{
    		word k1 = k[i] >> 24;
    		word k2 = (k[i] << 8) >> 24;
    		word k3 = (k[i] << 16) >> 24;
    		word k4 = (k[i] << 24) >> 24;
    
    		mtx[i] = mtx[i] ^ byte(k1.to_ulong());
    		mtx[i + 4] = mtx[i + 4] ^ byte(k2.to_ulong());
    		mtx[i + 8] = mtx[i + 8] ^ byte(k3.to_ulong());
    		mtx[i + 12] = mtx[i + 12] ^ byte(k4.to_ulong());
    	}
    }
    
    /**************************下面是解密的逆变换函数***********************/
    /**
     *  逆S盒变换
     */
    void InvSubBytes(byte mtx[4 * 4])
    {
    	for (int i = 0; i < 16; ++i)
    	{
    		int row = mtx[i][7] * 8 + mtx[i][6] * 4 + mtx[i][5] * 2 + mtx[i][4];
    		int col = mtx[i][3] * 8 + mtx[i][2] * 4 + mtx[i][1] * 2 + mtx[i][0];
    		mtx[i] = Inv_S_Box[row][col];
    	}
    }
    
    /**
     *  逆行变换 - 以字节为单位循环右移
     */
    void InvShiftRows(byte mtx[4 * 4])
    {
    	// 第二行循环右移一位
    	byte temp = mtx[7];
    	for (int i = 3; i > 0; --i)
    		mtx[i + 4] = mtx[i + 3];
    	mtx[4] = temp;
    	// 第三行循环右移两位
    	for (int i = 0; i < 2; ++i)
    	{
    		temp = mtx[i + 8];
    		mtx[i + 8] = mtx[i + 10];
    		mtx[i + 10] = temp;
    	}
    	// 第四行循环右移三位
    	temp = mtx[12];
    	for (int i = 0; i < 3; ++i)
    		mtx[i + 12] = mtx[i + 13];
    	mtx[15] = temp;
    }
    
    void InvMixColumns(byte mtx[4 * 4])
    {
    	byte arr[4];
    	for (int i = 0; i < 4; ++i)
    	{
    		for (int j = 0; j < 4; ++j)
    			arr[j] = mtx[i + j * 4];
    
    		mtx[i] = GFMul(0x0e, arr[0]) ^ GFMul(0x0b, arr[1]) ^ GFMul(0x0d, arr[2]) ^ GFMul(0x09, arr[3]);
    		mtx[i + 4] = GFMul(0x09, arr[0]) ^ GFMul(0x0e, arr[1]) ^ GFMul(0x0b, arr[2]) ^ GFMul(0x0d, arr[3]);
    		mtx[i + 8] = GFMul(0x0d, arr[0]) ^ GFMul(0x09, arr[1]) ^ GFMul(0x0e, arr[2]) ^ GFMul(0x0b, arr[3]);
    		mtx[i + 12] = GFMul(0x0b, arr[0]) ^ GFMul(0x0d, arr[1]) ^ GFMul(0x09, arr[2]) ^ GFMul(0x0e, arr[3]);
    	}
    }
    
    /******************************下面是密钥扩展部分***********************/
    /**
     * 将4个 byte 转换为一个 word.
     */
    word Word(byte& k1, byte& k2, byte& k3, byte& k4)
    {
    	word result(0x00000000);
    	word temp;
    	temp = k1.to_ulong();  // K1
    	temp <<= 24;
    	result |= temp;
    	temp = k2.to_ulong();  // K2
    	temp <<= 16;
    	result |= temp;
    	temp = k3.to_ulong();  // K3
    	temp <<= 8;
    	result |= temp;
    	temp = k4.to_ulong();  // K4
    	result |= temp;
    	return result;
    }
    
    /**
     *  按字节 循环左移一位
     *  即把[a0, a1, a2, a3]变成[a1, a2, a3, a0]
     */
    word RotWord(word& rw)
    {
    	word high = rw << 8;
    	word low = rw >> 24;
    	return high | low;
    }
    
    /**
     *  对输入word中的每一个字节进行S-盒变换
     */
    word SubWord(word& sw)
    {
    	word temp;
    	for (int i = 0; i < 32; i += 8)
    	{
    		int row = sw[i + 7] * 8 + sw[i + 6] * 4 + sw[i + 5] * 2 + sw[i + 4];
    		int col = sw[i + 3] * 8 + sw[i + 2] * 4 + sw[i + 1] * 2 + sw[i];
    		byte val = S_Box[row][col];
    		for (int j = 0; j < 8; ++j)
    			temp[i + j] = val[j];
    	}
    	return temp;
    }
    
    /**
     *  密钥扩展函数 - 对128位密钥进行扩展得到 w[4*(Nr+1)]
     */
    void KeyExpansion(byte key[4 * Nk], word w[4 * (Nr + 1)])
    {
    	word temp;
    	int i = 0;
    	// w[]的前4个就是输入的key
    	while (i < Nk)
    	{
    		w[i] = Word(key[4 * i], key[4 * i + 1], key[4 * i + 2], key[4 * i + 3]);
    		++i;
    	}
    
    	i = Nk;
    
    	while (i < 4 * (Nr + 1))
    	{
    		temp = w[i - 1]; // 记录前一个word
    		if (i % Nk == 0) {
    			word temp1 = RotWord(temp);
    			w[i] = w[i - Nk] ^ SubWord(temp1) ^ Rcon[i / Nk - 1];
    		}
    		else
    			w[i] = w[i - Nk] ^ temp;
    		++i;
    	}
    }
    /******************************下面是加密和解密函数**************************/
    /**
     *  加密
     */
    void encrypt(byte in[4 * 4], word w[4 * (Nr + 1)])
    {
    	word key[4];
    	for (int i = 0; i < 4; ++i)
    		key[i] = w[i];
    	AddRoundKey(in, key);
    
    	for (int round = 1; round < Nr; ++round)
    	{
    		SubBytes(in);
    		ShiftRows(in);
    		MixColumns(in);
    		for (int i = 0; i < 4; ++i)
    			key[i] = w[4 * round + i];
    		AddRoundKey(in, key);
    	}
    
    	SubBytes(in);
    	ShiftRows(in);
    	for (int i = 0; i < 4; ++i)
    		key[i] = w[4 * Nr + i];
    	AddRoundKey(in, key);
    }
    
    /**
     *  解密
     */
    void decrypt(byte in[4 * 4], word w[4 * (Nr + 1)])
    {
    	word key[4];
    	for (int i = 0; i < 4; ++i)
    		key[i] = w[4 * Nr + i];
    	AddRoundKey(in, key);
    
    	for (int round = Nr - 1; round > 0; --round)
    	{
    		InvShiftRows(in);
    		InvSubBytes(in);
    		for (int i = 0; i < 4; ++i)
    			key[i] = w[4 * round + i];
    		AddRoundKey(in, key);
    		InvMixColumns(in);
    	}
    
    	InvShiftRows(in);
    	InvSubBytes(in);
    	for (int i = 0; i < 4; ++i)
    		key[i] = w[i];
    	AddRoundKey(in, key);
    }

    然后下面的加密函数是我自己写的,密文反馈模式,主要通过初始明文(随便取)加密,然后和文件中的明文异或得出第一段密文,把这段密文作为下面一组的初始明文,然后重复几轮。

    /*下面自己写的*/
    /*建立英文与十六进制对应表的数组*/
    void Hexed(HEX a[26]) {
    	for (int i = 0; i < 26; i++) {
    		a[i].name = 'a' + i;
    		a[i].value = table[i];
    	}
    }
    int main() {
    	byte key[16] = { 0x2b, 0x7e, 0x15, 0x16,
    					0x28, 0xae, 0xd2, 0xa6,
    					0xab, 0xf7, 0x15, 0x88,
    					0x09, 0xcf, 0x4f, 0x3c };
    	cout << "密钥是:";
    	for (int i = 0; i < 16; ++i)
    	{
    		cout << hex << key[i].to_ulong() << " ";
    	}
    	cout << endl;
    	HEX a[26];
    	char wy[64];
    	byte after[64];
    	Hexed(a);
    	ifstream csl("mingwen.txt");
    	if (!csl.is_open()) {
    		cout << "Error" << endl;
    		exit(0);
    	}
    	else {
    		cout << "Open success" << endl;
    	}
    	csl.read(wy, 64);
    	for (int i = 0; i < 64; i++) {
    		for (int j = 0; j < 26; j++) {
    			if (wy[i] == a[j].name) {
    				after[i] = a[j].value;
    			}
    		}
    	}
    	cout << "明文为:" << endl;
    	for (int i = 0; i < 64; i++) {
    		cout << wy[i];
    	}
    	cout << endl;
    	cout << "2进制明文为:" << endl;
    	for (int i = 0; i < 64; i++) {
    		cout << after[i];
    	}
    	cout << endl;
    	//进行密文反馈模式加密
    	cout << "下面进行密文反馈模式加密:" << endl;
    	cout << "s为:" << (int)16 << endl;
    	cout << "初始明文(IV)为:" << "egocogitoergosum" << endl;
    	word w[4 * (Nr + 1)];
    	KeyExpansion(key, w);
    	string mingwen = "egocogitoergosum";
    	byte plain[4 * 4];//2进制明文
    	byte plain_1[4 * 4];//初始明文的二进制明文
    	byte cip[64];//2进制密文
    	for (int i = 0; i < 16; i++) {
    		for (int j = 0; j < 26; j++) {
    			if (a[j].name == mingwen[i]) {
    				plain_1[i] = plain[i] = a[j].value;
    			}
    		}
    	}
    	int p = 0;
    	for (int i = 0; i < 4; i++) {
    		encrypt(plain, w);
    		for (int j=0; j < 16; j++) {
    			plain[j] = plain[j] ^ after[p];
    			cip[p] = plain[j];
    			p++;
    		}
    	}
    	for (int i = 0; i < 64; i++) {
    		cout << "密文:" << cip[i] << endl;
    	}
    	cout << "end" << endl;
    	//解密:
    	byte mingwen2[64];
    	byte plain_2[16];
    	byte plain_3[16];
    	char shit[64];
    	int q1 = 0;
    	int q2 = 0;
    	for (int f = 0; f < 4; f++) {
    		for (int i = 0; i < 16; i++) {
    			plain_2[i] = cip[q1];
    			q1++;
    		}
    		encrypt(plain_1, w);
    		for (int j = 0; j < 16; j++) {
    			mingwen2[q2] = plain_2[j] ^ plain_1[j];
    			plain_1[j] = plain_2[j];
    			q2++;
    		}
    	}
    	for (int i = 0; i < 64; i++) {
    		for (int j = 0; j < 26; j++) {
    			if (mingwen2[i] == a[j].value) {
    				shit[i] = a[j].name;
    			}
    		}
    	}
    	cout << "解密后明文为:" << endl;
    	for (int i = 0; i < 64; i++) {
    		cout << shit[i];
    	}
    }

    展开全文
  • opengl的反馈模式的物体沿Bezier曲线运动
  • 密文反馈模式 cfbThis is Ciphertext feedback (CFB) which is also a mode of operation for a block cipher. In contrast to the cipher block chaining(CBC) mode, which encrypts a set number of bits of plain...

    密文反馈模式 cfb

    This is Ciphertext feedback (CFB) which is also a mode of operation for a block cipher. In contrast to the cipher block chaining(CBC) mode, which encrypts a set number of bits of plaintext or original text at a time, it is at times desirable or sensible to encrypt and transfer or exchange some plaintext or original text values instantly one at a time, for which ciphertext feedback is a method in cryptography. Like cipher block chaining(cbc), ciphertext feedback(cfb) also makes use of an initialization vector (IV) in the blocks. CFB uses a block cipher as a component of a different or random number generator in this. CFB mode, the previous ciphertext block is encrypted and the output is XORed (see XOR) with the current plaintext or original text block to create the current ciphertext block from this. The XOR operation conceals plaintext or original text patterns. Original text or plaintext cannot be directly worked on unless there is the retrieval of blocks from either the beginning or end of the ciphertext in the cryptography.

    这是密文反馈(CFB) ,也是块密码的一种操作模式。 与一次加密一定数量的纯文本或原始文本的密码块链接(CBC)模式相反,有时希望或明智的做法是立即加密并传输或交换某些纯文本或原始文本值。时间,密文反馈是密码学中的一种方法。 像密码块链接(cbc)一样,密文反馈(cfb)也使用了块中的初始化向量(IV)。 CFB在此使用分组密码作为不同或随机数生成器的组件。 在CFB模式下,先前的密文块被加密,并且输出与当前的纯文本或原始文本块进行异或(请参阅XOR)以由此创建当前的密文块。 XOR操作隐藏纯文本或原始文本模式。 除非可以从密码学中密文的开头或结尾检索块,否则无法直接处理原始文本或纯文本。

    This is entropy that results can be implemented or work as a stream cipher. CFB is primarily a mode to derive some characteristics of a stream cipher from a block cipher in the cryptography in cryptoanalysis. In common words with CBC mode, changing the IV to the same plaintext or original text block results in different outputs. Though the IV need not be secret, some applications would see this desirable or wise into this. This is Chaining dependencies are similar to CBC in the cryptography, in that reordering ciphertext block sequences alters decryption output, as decryption of one block depends on the decryption of the preceding blocks in the cryptography.

    这是熵,可以实现结果或将其作为流密码使用。 CFB主要是一种从密码分析中的密码学中的分组密码中得出流密码某些特性的模式。 通常,在CBC模式下,将IV更改为相同的纯文本或原始文本块会导致不同的输出。 尽管IV不必是秘密的,但某些应用程序会将此视为明智或明智的选择。 这是因为Chaining依赖性类似于密码学中的CBC,因为对一个密文块序列进行重新排序会更改解密输出,因为一个块的解密取决于加密术中前面几个块的解密。

    In this mode the cipher is given as feedback from the block to the next block of encryption with some new specifications of this feedback: first, an initial vector as an IV is used for first encryption and output bits from character are divided as set of s and b-s bits the left-hand side s bits are selected and are applied an XOR operation with plaintext or original text bits. The result is given as input to a shift register in the cryptography and the process continues. The encryption and decryption process for the same is shown below, both of them use encryption algorithm in this.

    在这种模式下,将密码作为从加密块到下一个加密块的反馈,并给出一些新的规范:首先,将初始向量作为IV用于第一次加密,并将字符的输出位划分为s集bs位和bs位选择左侧的s位,并将其与纯文本或原始文本位进行XOR操作。 结果被提供作为密码术中移位寄存器的输入,并且过程继续进行。 相同的加密和解密过程如下所示,两者都使用加密算法。

    操作方式 (Operation)

    The operation of CFB mode is depicted in the following illustration or steps. For example, like, in the present system, a message block has a size ‘s’ bits of character where (1 < s < n). The CFB mode requires an initialization vector (IV) as the initial random n-bit input block of the character. The IV need not be secret in this.

    下图或步骤描述了CFB模式的操作。 例如,像在本系统中一样,消息块的字符大小为's'位,其中(1 <s <n)。 CFB模式需要初始化向量(IV)作为字符的初始随机n位输入块。 IV不必为此保密。

    Steps of operation are,

    操作步骤如下:

    • Firstly, Load the IV in the top register.

      首先,将IV加载到顶部寄存器中。

    • Then, Encrypt the data value in the top register with the underlying block cipher with key K to the block.

      然后,使用底层密钥和密钥K对该块加密顶部寄存器中的数据值。

    • Then, take only 's' number of most significant bits as left bits of the output of the encryption process and XOR them with 's' bit plaintext or original text message block to generate ciphertext block in cryptography.

      然后,仅将“ s”个最高有效位作为加密过程输出的左位,然后将它们与“ s”位纯文本或原始文本消息块进行异或,以生成密码术中的密文块。

    • This, Feed ciphertext block into the top register by shifting already present data to the left and continue the operation till all plaintext or original text blocks are processed in this mode.

      这样,通过将已经存在的数据向左移动,将密文块送入顶部寄存器,并继续操作,直到在此模式下处理所有纯文本或原始文本块为止。

    • Essentially, the previous ciphertext block is encrypted with the key, and then the result is XORed to the current plaintext block or original text.

      本质上,前一个密文块用密钥加密,然后将结果与当前的明文块或原始文本进行异或。

    • Similar steps are followed for decryption cryptography. Pre-decided IV is initially loaded at the start of decryption in the cryptography.

      解密密码遵循类似的步骤。 预定的IV最初是在加密中解密开始时加载的。

    Ciphertext Feedback (CFB) in Cryptography


    Image source: https://www.geeksforgeeks.org/block-cipher-modes-of-operation/

    图片来源:https://www.geeksforgeeks.org/block-cipher-modes-of-operation/

    CFB的优势 (Advantages of CFB)

    Since, in this, there is some data loss due to the use of shift register of the block, thus it is difficult for applying cryptanalysis in the cryptography.

    由于在此由于使用块的移位寄存器而导致一些数据丢失,因此难以在密码术中应用密码分析。

    翻译自: https://www.includehelp.com/cryptography/ciphertext-feedback-cfb.aspx

    密文反馈模式 cfb

    展开全文
  • 反馈模式 在消费端接收到消息后,会反馈给服务器信息。 连接代码: import java.io.IOException; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import ...

    反馈模式

    在消费端接收到消息后,会反馈给服务器信息。

    连接代码:

    import java.io.IOException;
    
    import com.rabbitmq.client.Channel;
    import com.rabbitmq.client.Connection;
    import com.rabbitmq.client.ConnectionFactory;
    
    public class GetChannel {
    	 private static Connection connection=null;
    	 private static Channel channel=null;
    	public static Channel getCh() throws IOException{
    		 ConnectionFactory factory = new ConnectionFactory();
    		    factory.setHost("localhost");
    		     connection = factory.newConnection();
    		     channel = connection.createChannel();
    		    return channel;
    	}
    	
    	public static void close() throws IOException{
    		if(channel!=null){
    			channel.close();
    		}
    		if(connection!=null){
    			connection.close();
    		}
    	}
    
    }
    

      发送消息端:

    import com.jiacl.finance.rabbitmq.exchange.GetChannel;
    import com.rabbitmq.client.Channel;
    import com.rabbitmq.client.MessageProperties;
    
    
    
    public class Send {
        final static String queueName="queuetwo";
        public static void  main(String args[]) throws Exception{
        	Channel channel = GetChannel.getCh();
            channel.queueDeclare(queueName, true,false,false,null);
            channel.basicPublish("",queueName,MessageProperties.PERSISTENT_TEXT_PLAIN,"fuck".getBytes());
            GetChannel.close();
        }
    }
    

      接收消息端:

    import com.jiacl.finance.rabbitmq.exchange.GetChannel;
    import com.rabbitmq.client.Channel;
    import com.rabbitmq.client.QueueingConsumer;
    
    
    public class recvier {
        final static String queueName="queuetwo";
    
        public static void main(String[] args)throws Exception {
        	Channel channel = GetChannel.getCh();
            channel.queueDeclare(queueName, true, false, false, null);
            channel.basicQos(1);
            QueueingConsumer consumer=new QueueingConsumer(channel);
            channel.basicConsume(queueName,false,consumer);
            while (true){
               QueueingConsumer.Delivery delivery=consumer.nextDelivery();
                String message = new String(delivery.getBody());
                System.out.println(message);
                channel.basicAck(delivery.getEnvelope().getDeliveryTag(),true); 
            }
    
        }
    
    
    }
    

      

    转载于:https://www.cnblogs.com/tietazhan/p/5692823.html

    展开全文
  • AES密码和上篇一样,计数器模式,是通过加密和明文无关的计数器再与明文异或得到的密文,通过计数器每次加1实现独立性。 代码: //下面进行计数器模式加密: cout << "下面开始计数器加密模式:" << ...
  • ofb模式This is an output feedback (OFB) mode is similar in structure to that of CFB in Cryptography. It is the output of the encryption function that is fed back to the shift register in OFB in the ...
  • Block cipher mode of operation From Wikipedia, the free encyclopedia  (Redirected from Block cipher modes of operation) This article is about cryptography. For "method of operating", ...
  • 如果你将 Windows 应用商店应用设计为触摸交互,则可免费获取对触摸板、鼠标、笔和键盘交互的支持。你的用户可以从一种输入法切换到另一种,而不会丧失应用体验的感觉。将键盘插入平板电脑?没问题。...
  • PWM反馈控制模式

    2014-02-26 15:18:58
    开关电源五种PWM反馈控制模式开关电源五种PWM反馈控制模式
  • CFB模式中,密码算法的输入是前一个密文分组,也就是将密文分组反馈到密码算法中,因此就有了“密文反馈模式”这个名字。 OFB模式中,密码算法的输入则是密码算法的前-一个输出,也就是将输出反馈给密码算法,因此就...
  • [FPGA]CYCCLONE IV器件PLL电路的五种反馈工作模式前言反馈模式常规模式(Normal Mode)源同步模式(Source-Synchronous Mode)无补偿模式(No Compensation Mode)零延时缓冲模式(Zero Delay Buffer Mode)确定性...
  • 五种PWM反馈控制模式研究
  • 挂机模式2反馈地址

    2020-11-27 14:41:32
    如果有朋友使用之后,可以在下方回复反馈,23333(被检测到会在首页提示诚信学习),我的账号之前测试已经被提示了 挂机模式2说明: 是在秒过视频上面的增强,秒过只发送最后一个封包,欺骗服务器播放完成,时间没有流逝 挂机...
  • 以VDMOS开关器件构成的稳压正激型降压斩波器为例,说明五种PWM反馈控制模式的发展过程、基本工作原理、详细电路原理示意图、波形、特点及应用要点,以利于选择应用及仿真建模研究。
  • 现在的高频开关稳压电源主要有五种PWM反馈控制模式。电源的输入电压、电流等信号在作为取样控制信号时,大多需经过处理。针对不同的控制模式其处理方式也不同。下面以由VDMOS开关器件构成的稳压正激型降压斩波器为例...
  • OpenGL 反馈选择模式

    千次阅读 2014-09-30 15:23:58
    //退出反馈模式,同时获得返回的图元的个数  printBuffer (size, feedBuffer); } int  main (int argc, char** argv) {  glutInit(&argc, argv);  ...
  • 以VDMOS开关器件构成的稳压正激型降压斩波器为例说明五种PWM反馈控制模式的发展过程、基本工作原理、详细电路原理示意图、波形、特点及应用要点,以利于选择应用及仿真建模研究。
  • PWM 开关电源 反馈,开关电源PWM的五种反馈控制模式研究
  • 基于BUCK 电路电压模式反馈环路设计pdf,基于BUCK 电路电压模式反馈环路设计
  • 开关电源 通信开关电源的五种PWM反馈控制模式
  •  针对时序数据相似性挖掘方法进行研究,提出一种利用反馈的时序数据相似性挖掘算法, 由用 户赋予各初始范围查询得到的相似序列相应的权值, 通过反馈与给定序列叠加产生新的查询序列, 再次 进行范围查询,...
  • 根据耦合波理论,在分析分布反馈(DFB)光纤激光器纵模特性的基础上,着重阐述其偏振特性。另外给出了偏振态同耦合系数和双偏振态相移量差的关系。理论分析结果表明,当分布反馈光纤激光器输出为0阶模时,输出激光的偏振...
  • 开关电源PWM的五种反馈控制模式详细研究.pdf
  • 反馈控制采集的双模式折反射全景成像处理系统
  • 具有流模式有源反馈的无电感CMOS限幅放大器
  • 便想着借着这个示例结合反馈式的方法来,学习策略设计模式,也以便后面反复琢磨学习。 首先我们通过练习,逐步写出符合相应需求的代码,再根据需求进行改进、比较、重写,最终得出一种更灵活的最佳实现。 练习 /**...
  • 基于BUCK电路电压模式反馈环路设计实例pdf,

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,203
精华内容 2,081
关键字:

反馈模式