• 2021国赛CISCN 初赛 部分REwriteup


    glass

    题目名称:glass
    题目描述:Reverse sign in,flag形式为"CISCN{XXXXX}"
    

    首先查看apk

    界面如下

    用AndroidKiller打开,反编译成java源码

    这里只是声明了一下checkflag函数 要去native-lib里找

    分析glassProjectlibarmeabi-v7a中的libnative-lib.so

    IDA打开

    怀疑是RC4加密 参考 https://www.cnblogs.com/SunsetR/p/12247041.html

    bool __fastcall Java_com_ciscn_glass_MainActivity_checkFlag(int a1, int a2, int a3)
    {
      const char *v3; // r4
      size_t v4; // r5
      int v6; // [sp+0h] [bp-220h]
      char v7; // [sp+100h] [bp-120h]
    
      v3 = (const char *)sub_F0C(a1, a3);
      if ( strlen(v3) != 39 )                   //flag长度为39
        return 0;
      _aeabi_memclr8(&v7, 256);                
      _aeabi_memcpy8(&v6, "12345678", 256);		//定义v6 v7 给v6赋值12345678
      v4 = strlen((const char *)&v6);    		//v4为v6的长度 8
      sub_FFC(&v7, &v6, v4);					//RC4填充S盒,s盒乱序
      sub_1088(&v7, v3, 39);					//RC4计算密钥流,异或加密
      sub_10D4(v3, 39, &v6, v4);				//自己搞得加密
      return memcmp(v3, &unk_497C, 0x27u) == 0;
    }
    
    unk_497C
    0xa3, 0x1a, 0xe3, 0x69, 0x2f, 0xbb, 0x1a, 0x84, 0x65, 0xc2, 0xad, 0xad, 0x9e, 0x96, 0x5, 0x2, 0x1f, 0x8e, 0x36, 0x4f, 0xe1, 0xeb, 0xaf, 0xf0, 0xea, 0xc4, 0xa8, 0x2d, 0x42, 0xc7, 0x6e, 0x3f, 0xb0, 0xd3, 0xcc, 0x78, 0xf9, 0x98, 0x3f
    
     sub_10D4(v3, 39, &v6, v4);
     int __fastcall sub_10D4(int result, int a2, int a3, int a4)
    {
      int i; // r4
      int v5; // r6
      char v6; // r5
      char v7; // lr
      char v8; // r12
      int j; // lr
      int k; // r6
    
      for ( i = 0; i < a2; i += 3 )
      {
        v5 = result + i;
        v6 = *(_BYTE *)(result + i + 2);
        v7 = *(_BYTE *)(result + i + 1);
        v8 = *(_BYTE *)(result + i) ^ v6;
        *(_BYTE *)(result + i) = v8;
        *(_BYTE *)(v5 + 2) = v6 ^ v7;
        *(_BYTE *)(v5 + 1) = v7 ^ v8;   //交换异或
      }
      for ( j = 0; j < a2; j += a4 )
      {
        for ( k = 0; (a4 & ~(a4 >> 31)) != k && j + k < a2; ++k )
          *(_BYTE *)(result + k) ^= *(_BYTE *)(a3 + k); //分别异或12345678
        result += a4;
      }
      return result;
    }
    

    解题代码如下

    #include <stdio.h>
    #include <windows.h>
    
    
    unsigned char *base64_encode(unsigned char *str)
    {
        long len;
        long str_len;
        unsigned char *res;
        int i,j;
    //定义base64编码表
        unsigned char *base64_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    
    //计算经过base64编码后的字符串长度
        str_len=strlen(str);
        if(str_len % 3 == 0)
            len=str_len/3*4;
        else
            len=(str_len/3+1)*4;
    
        res=malloc(sizeof(unsigned char)*len+1);
        res[len]='';
    
    //以3个8位字符为一组进行编码
        for(i=0,j=0;i<len-2;j+=3,i+=4) {="" res[i]="base64_table[str[j]">>2]; //取出第一个字符的前6位并找出对应的结果字符
            res[i+1]=base64_table[(str[j]&0x3)<<4 | (str[j+1]>>4)]; //将第一个字符的后位与第二个字符的前4位进行组合并找到对应的结果字符
            res[i+2]=base64_table[(str[j+1]&0xf)<<2 | (str[j+2]>>6)]; //将第二个字符的后4位与第三个字符的前2位组合并找出对应的结果字符
            res[i+3]=base64_table[str[j+2]&0x3f]; //取出第三个字符的后6位并找出结果字符
        }
    
        switch(str_len % 3)
        {
            case 1:
                res[i-2]='=';
                res[i-1]='=';
                break;
            case 2:
                res[i-1]='=';
                break;
        }
    
        return res;
    }
    
    int main(){
    	int j=0,i=0;
    
        byte result[]  = { 0xa3, 0x1a, 0xe3, 0x69, 0x2f, 0xbb, 0x1a,  0x84, 0x65,0xc2,0xad, 0xad,  0x9e, 0x96, 0x5, 0x2, 0x1f, 0x8e, 0x36, 0x4f,  0xe1,  0xeb,0xaf,  0xf0,  0xea,  0xc4,  0xa8, 0x2d, 0x42,  0xc7, 0x6e, 0x3f, 0xb0,  0xd3,0xcc, 0x78,  0xf9,  0x98, 0x3f};
        char key[] = "1234567812345678123456781234567812345678";
    
        for (i = 0; i < sizeof(result); i++) {
            result[i] = result[i] ^ key[i];
        }
        for (j = 0; j < sizeof(result); j += 3) {
            result[j + 1] =  result[j + 1] ^ result[j];
            result[j + 2] = result[j + 2] ^ result[j + 1];
            result[j] = result[j] ^ result[j + 2];
        }
        char* flag = base64_encode(result);
        printf(flag);
    
    
        return 0;
    }
    
    

    +Lpql0fK6JHFB273kgs5khSor36qUEWNbS22hm6fhl7fsx5SpmJq

    秘钥12345678

    CISCN{6654d84617f627c88846c172e0f4d46c}

    babybc

    方法一:

    手撕出来的(惭愧)

    有约束条件的数独 给出了两个数

    拿到bc文件

    根据https://stackoverflow.com/questions/32523847/how-to-make-llvm-bc-file-executable导出32位elf文件

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      size_t v3; // rax
      unsigned __int64 v4; // rcx
      unsigned __int8 v5; // dl
    
      __isoc99_scanf(&unk_402004, x, envp);
      if ( (unsigned int)strlen(x) == 25 ) //25位flag
      {//数组所有的元素都<=5
        if ( x[0] ) 
        {
          if ( (unsigned __int8)(x[0] - 48) > 5u )
            return 0;
          v3 = strlen(x);
          v4 = 1LL;
          while ( v4 < v3 )
          {
            v5 = x[v4++] - 48;//chr数字转int数字
            if ( v5 > 5u )
              return 0;
          }
        }
        if ( f((__int64)x) && c() )//两个check函数都得为1
          printf("CISCN{MD5(%s)}", x);
      }
      return 0;
    }
    
    char __fastcall f(__int64 a1)
    {
      __int64 v1; // rax
      __int64 i; // rcx
      char v3; // dl
      char v4; // dl
      char v5; // dl
      char v6; // dl
      char v7; // dl
    //填充数字 m[]为0则填充 不为0则判断输入的数是否为0,不为0报错 所以要让m[]中不为0位置的输入为0
        //这个函数的作用就是 让m[]中的4 3 位置输入为0
      v1 = 4LL;
      for ( i = 0LL; i < 5; ++i )
      {
        v3 = *(_BYTE *)(a1 + v1 - 4);
        if ( m[v1 - 4] )
        {
          if ( v3 != 48 )
            return 0;
        }
        else
        {
          if ( v3 == 48 )
            return 0;
          m[v1 - 4] = v3 - 48;
        }
        v4 = *(_BYTE *)(a1 + v1 - 3);
        if ( m[v1 - 3] )
        {
          if ( v4 != 48 )
            return 0;
        }
        else
        {
          if ( v4 == 48 )
            return 0;
          m[v1 - 3] = v4 - 48;
        }
        v5 = *(_BYTE *)(a1 + v1 - 2);
        if ( m[v1 - 2] )
        {
          if ( v5 != 48 )
            return 0;
        }
        else
        {
          if ( v5 == 48 )
            return 0;
          m[v1 - 2] = v5 - 48;
        }
        v6 = *(_BYTE *)(a1 + v1 - 1);
        if ( m[v1 - 1] )
        {
          if ( v6 != 48 )
            return 0;
        }
        else
        {
          if ( v6 == 48 )
            return 0;
          m[v1 - 1] = v6 - 48;
        }
        v7 = *(_BYTE *)(a1 + v1);
        if ( m[v1] )
        {
          if ( v7 != 48 )
            return 0;
        }
        else
        {
          if ( v7 == 48 )
            return 0;
          m[v1] = v7 - 48;
        }
        v1 += 5LL;
      }
      return 1;
    }
    
    char c()
    {
      unsigned __int8 *v0; // rax
      __int64 v1; // rdx
      __int64 v2; // rsi
      __int64 v3; // rsi
      __int64 v4; // rsi
      __int64 v5; // rsi
      __int64 v6; // rax
      __int64 v7; // rdx
      __int64 v8; // rdx
      __int64 v9; // rdx
      __int64 v10; // rdx
      unsigned __int8 *v11; // rax
      __int64 v12; // rdx
      char v13; // cl
      char v14; // cl
      char v15; // cl
      char v16; // cl
      __int64 v17; // rdx
      __int64 v18; // rsi
      char result; // al
      char v20; // al
      char v21; // al
      char v22; // al
      char v23; // al
      char v24; // al
      int v25; // [rsp+0h] [rbp-10h]
      __int16 v26; // [rsp+4h] [rbp-Ch]
      int v27; // [rsp+8h] [rbp-8h]
      __int16 v28; // [rsp+Ch] [rbp-4h]
    
      v0 = &m[4];
      v1 = 0LL;
      while ( 1 )
      {
        v28 = 0;
        v27 = 0;
        v2 = *(v0 - 4);
        if ( *((_BYTE *)&v27 + v2) )
          break;
        *((_BYTE *)&v27 + v2) = 1;
        v3 = *(v0 - 3);
        if ( *((_BYTE *)&v27 + v3) )
          break;
        *((_BYTE *)&v27 + v3) = 1;
        v4 = *(v0 - 2);
        if ( *((_BYTE *)&v27 + v4) )
          break;
        *((_BYTE *)&v27 + v4) = 1;
        v5 = *(v0 - 1);
        if ( *((_BYTE *)&v27 + v5) )
          break;
        *((_BYTE *)&v27 + v5) = 1;
        if ( *((_BYTE *)&v27 + *v0) )
          break;
        ++v1;
        v0 += 5;
        if ( v1 >= 5 )
        {
          v6 = 0LL;
          while ( 1 )
          {
            v26 = 0;
            v25 = 0;
            v7 = m[v6];
            if ( *((_BYTE *)&v25 + v7) )
              break;
            *((_BYTE *)&v25 + v7) = 1;
            v8 = m[v6 + 5];
            if ( *((_BYTE *)&v25 + v8) )
              break;
            *((_BYTE *)&v25 + v8) = 1;
            v9 = m[v6 + 10];
            if ( *((_BYTE *)&v25 + v9) )
              break;
            *((_BYTE *)&v25 + v9) = 1;
            v10 = m[v6 + 15];
            if ( *((_BYTE *)&v25 + v10) )
              break;
            *((_BYTE *)&v25 + v10) = 1;
            if ( *((_BYTE *)&v25 + m[v6 + 20]) )
              break;
    //关键代码在这 两个循环分别代表行 和 列 
    //n是行 o是列 m是整个地图
              
            if ( ++v6 >= 5 )
            {
              v11 = &m[4];
              v12 = 0LL;
              //4个判断 因为5*5的棋盘 两两比较 只需要四次 
                  /*n[]={0,0,0,1 
                  		 1,0,0,0 
                  		 2,0,0,1
                  		 0,0,0,0
                  		 1,0,1,0 有用的就到这
                  		 0,0,0,0
                  		 0,0,0,0
                  		 0,0,0,0}
                  */
             //1 左大 2 右大
              while ( 1 ) {	 
                v13 = n[4 * v12];
                if ( v13 == 2 )
                {
                  if ( *(v11 - 4) > *(v11 - 3) )
                    return 0;
                }
                else if ( v13 == 1 && *(v11 - 4) < *(v11 - 3) )
                {
                  return 0;
                }
                v14 = n[4 * v12 + 1];
                if ( v14 == 1 )
                {
                  if ( *(v11 - 3) < *(v11 - 2) )
                    return 0;
                }
                else if ( v14 == 2 && *(v11 - 3) > *(v11 - 2) )
                {
                  return 0;
                }
                v15 = n[4 * v12 + 2];
                if ( v15 == 2 )
                {
                  if ( *(v11 - 2) > *(v11 - 1) )
                    return 0;
                }
                else if ( v15 == 1 && *(v11 - 2) < *(v11 - 1) )
                {
                  return 0;
                }
                v16 = n[4 * v12 + 3];
                if ( v16 == 2 )
                {
                  if ( *(v11 - 1) > *v11 )
                    return 0;
                }
                else if ( v16 == 1 && *(v11 - 1) < *v11 )
                {
                  return 0;
                }
                ++v12;
                v11 += 5;
                if ( v12 >= 5 )
                {
                  v17 = 4LL;
                  v18 = 0LL;
                    /*o[]表示列
                    o[]={0,0,2,0
                    	2,0,0,0
                    	0,0,0,0
                    	0,1,0,0
                    	1,0,0,1}
                    	1 上大 2 下大
                        每列的12 23 34 45分别比较
                    */
                  while ( 1 )
                  {
                    v20 = o[v17 - 4];
                    if ( v20 == 2 )
                    {
                      if ( m[v17 - 4] < m[v17 + 1] )
                        return 0;
                    }
                    else if ( v20 == 1 && m[v17 - 4] > m[v17 + 1] )
                    {
                      return 0;
                    }
                    v21 = o[v17 - 3];
                    if ( v21 == 1 )
                    {
                      if ( m[v17 - 3] > m[v17 + 2] )
                        return 0;
                    }
                    else if ( v21 == 2 && m[v17 - 3] < m[v17 + 2] )
                    {
                      return 0;
                    }
                    v22 = o[v17 - 2];
                    if ( v22 == 2 )
                    {
                      if ( m[v17 - 2] < m[v17 + 3] )
                        return 0;
                    }
                    else if ( v22 == 1 && m[v17 - 2] > m[v17 + 3] )
                    {
                      return 0;
                    }
                    v23 = o[v17 - 1];
                    if ( v23 == 2 )
                    {
                      if ( m[v17 - 1] < m[v17 + 4] )
                        return 0;
                    }
                    else if ( v23 == 1 && m[v17 - 1] > m[v17 + 4] )
                    {
                      return 0;
                    }
                    v24 = o[v17];
                    if ( v24 == 2 )
                    {
                      if ( m[v17] < m[v17 + 5] )
                        return 0;
                    }
                    else if ( v24 == 1 && m[v17] > m[v17 + 5] )
                    {
                      return 0;
                    }
                    ++v18;
                    v17 += 5LL;
                    result = 1;
                    if ( v18 >= 4 )
                      return result;
                  }
                }
              }
            }
          }
          return 0;
        }
      }
      return 0;
    }
    

    根据所得条件 画出map图

    每行和每列都得有 12345并且不能有重复

    数独做出来后为

    14253 53142 35021 21504 42315

    测试一下

    md5后CISCN{8a04b4597ad08b83211d3adfa1f61431}

    方法二:

    下载文件后,发现是.bc文件,使用命令编译成可执行文件:
    llc -filetype=obj baby.bc
    gcc baby.o
    使用ida打开,发现主函数:

    
    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      size_t v3; // rax
      unsigned __int64 v4; // rcx
      unsigned __int8 v5; // dl
    
      __isoc99_scanf(&unk_402004, x, envp);
      if ( (unsigned int)strlen(x) == 25 )
      {
        if ( x[0] )
        {
          if ( (unsigned __int8)(x[0] - 48) > 5u )
            return 0;
          v3 = strlen(x);
          v4 = 1LL;
          while ( v4 < v3 )
          {
            v5 = x[v4++] - 48;
            if ( v5 > 5u )
              return 0;
          }
        }
        if ( f((__int64)x) && c() )
          printf("CISCN{MD5(%s)}", x);
      }
      return 0;
    }
    

    分析主函数可知:输入的长度为25位,并且每位都不大于5,最终flag为输入值的md5值外面加上CISCN{},经过f((int64)x) 和c()两个函数校验之后确定输入的值是不是flag.查看这两个函数:f((int64)x):

    
    char __fastcall f(__int64 a1)
    {
      signed __int64 v1; // rax
      signed __int64 v2; // rcx
      char v3; // dl
      char v4; // dl
      char v5; // dl
      char v6; // dl
      char v7; // dl
    
      v1 = 4LL;
      v2 = 0LL;
      do
      {
        v3 = *(_BYTE *)(a1 + v1 - 4);
        if ( m[v1 - 4] )
        {
          if ( v3 != 48 )
            return 0;
        }
        else
        {
          if ( v3 == 48 )
            return 0;
          m[v1 - 4] = v3 - 48;
        }
        v4 = *(_BYTE *)(a1 + v1 - 3);
        if ( m[v1 - 3] )
        {
          if ( v4 != 48 )
            return 0;
        }
        else
        {
          if ( v4 == 48 )
            return 0;
          m[v1 - 3] = v4 - 48;
        }
        v5 = *(_BYTE *)(a1 + v1 - 2);
        if ( m[v1 - 2] )
        {
          if ( v5 != 48 )
            return 0;
        }
        else
        {
          if ( v5 == 48 )
            return 0;
          m[v1 - 2] = v5 - 48;
        }
        v6 = *(_BYTE *)(a1 + v1 - 1);
        if ( m[v1 - 1] )
        {
          if ( v6 != 48 )
            return 0;
        }
        else
        {
          if ( v6 == 48 )
            return 0;
          m[v1 - 1] = v6 - 48;
        }
        v7 = *(_BYTE *)(a1 + v1);
        if ( m[v1] )
        {
          if ( v7 != 48 )
            return 0;
        }
        else
        {
          if ( v7 == 48 )
            return 0;
          m[v1] = v7 - 48;
        }
        ++v2;
        v1 += 5LL;
      }
      while ( v2 < 5 );
      return 1;
    }
    

    c():

    
    char c()
    {
      unsigned __int8 *v0; // rax
      signed __int64 v1; // rdx
      __int64 v2; // rsi
      __int64 v3; // rsi
      __int64 v4; // rsi
      __int64 v5; // rsi
      __int64 v6; // rax
      __int64 v7; // rdx
      __int64 v8; // rdx
      __int64 v9; // rdx
      __int64 v10; // rdx
      unsigned __int8 *v11; // rax
      signed __int64 v12; // rdx
      char v13; // cl
      char v14; // cl
      char v15; // cl
      char v16; // cl
      signed __int64 v17; // rdx
      signed __int64 v18; // rsi
      char result; // al
      char v20; // al
      char v21; // al
      char v22; // al
      char v23; // al
      char v24; // al
      int v25; // [rsp+0h] [rbp-10h]
      __int16 v26; // [rsp+4h] [rbp-Ch]
      int v27; // [rsp+8h] [rbp-8h]
      __int16 v28; // [rsp+Ch] [rbp-4h]
    
      v0 = &m[4];
      v1 = 0LL;
      while ( 1 )
      {
        v28 = 0;
        v27 = 0;
        v2 = *(v0 - 4);
        if ( *((_BYTE *)&v27 + v2) )
          break;
        *((_BYTE *)&v27 + v2) = 1;
        v3 = *(v0 - 3);
        if ( *((_BYTE *)&v27 + v3) )
          break;
        *((_BYTE *)&v27 + v3) = 1;
        v4 = *(v0 - 2);
        if ( *((_BYTE *)&v27 + v4) )
          break;
        *((_BYTE *)&v27 + v4) = 1;
        v5 = *(v0 - 1);
        if ( *((_BYTE *)&v27 + v5) )
          break;
        *((_BYTE *)&v27 + v5) = 1;
        if ( *((_BYTE *)&v27 + *v0) )
          break;
        ++v1;
        v0 += 5;
        if ( v1 >= 5 )
        {
          v6 = 0LL;
          while ( 1 )
          {
            v26 = 0;
            v25 = 0;
            v7 = m[v6];
            if ( *((_BYTE *)&v25 + v7) )
              break;
            *((_BYTE *)&v25 + v7) = 1;
            v8 = m[v6 + 5];
            if ( *((_BYTE *)&v25 + v8) )
              break;
            *((_BYTE *)&v25 + v8) = 1;
            v9 = m[v6 + 10];
            if ( *((_BYTE *)&v25 + v9) )
              break;
            *((_BYTE *)&v25 + v9) = 1;
            v10 = m[v6 + 15];
            if ( *((_BYTE *)&v25 + v10) )
              break;
            *((_BYTE *)&v25 + v10) = 1;
            if ( *((_BYTE *)&v25 + m[v6 + 20]) )
              break;
            if ( ++v6 >= 5 )
            {
              v11 = &m[4];
              v12 = 0LL;
              while ( 1 )
              {
                v13 = n[4 * v12];
                if ( v13 == 2 )
                {
                  if ( *(v11 - 4) > *(v11 - 3) )
                    return 0;
                }
                else if ( v13 == 1 && *(v11 - 4) < *(v11 - 3) )
                {
                  return 0;
                }
                v14 = n[4 * v12 + 1];
                if ( v14 == 1 )
                {
                  if ( *(v11 - 3) < *(v11 - 2) )
                    return 0;
                }
                else if ( v14 == 2 && *(v11 - 3) > *(v11 - 2) )
                {
                  return 0;
                }
                v15 = n[4 * v12 + 2];
                if ( v15 == 2 )
                {
                  if ( *(v11 - 2) > *(v11 - 1) )
                    return 0;
                }
                else if ( v15 == 1 && *(v11 - 2) < *(v11 - 1) )
                {
                  return 0;
                }
                v16 = n[4 * v12 + 3];
                if ( v16 == 2 )
                {
                  if ( *(v11 - 1) > *v11 )
                    return 0;
                }
                else if ( v16 == 1 && *(v11 - 1) < *v11 )
                {
                  return 0;
                }
                ++v12;
                v11 += 5;
                if ( v12 >= 5 )
                {
                  v17 = 4LL;
                  v18 = 0LL;
                  while ( 1 )
                  {
                    v20 = o[v17 - 4];
                    if ( v20 == 2 )
                    {
                      if ( m[v17 - 4] < m[v17 + 1] )
                        return 0;
                    }
                    else if ( v20 == 1 && m[v17 - 4] > m[v17 + 1] )
                    {
                      return 0;
                    }
                    v21 = o[v17 - 3];
                    if ( v21 == 1 )
                    {
                      if ( m[v17 - 3] > m[v17 + 2] )
                        return 0;
                    }
                    else if ( v21 == 2 && m[v17 - 3] < m[v17 + 2] )
                    {
                      return 0;
                    }
                    v22 = o[v17 - 2];
                    if ( v22 == 2 )
                    {
                      if ( m[v17 - 2] < m[v17 + 3] )
                        return 0;
                    }
                    else if ( v22 == 1 && m[v17 - 2] > m[v17 + 3] )
                    {
                      return 0;
                    }
                    v23 = o[v17 - 1];
                    if ( v23 == 2 )
                    {
                      if ( m[v17 - 1] < m[v17 + 4] )
                        return 0;
                    }
                    else if ( v23 == 1 && m[v17 - 1] > m[v17 + 4] )
                    {
                      return 0;
                    }
                    v24 = o[v17];
                    if ( v24 == 2 )
                    {
                      if ( m[v17] < m[v17 + 5] )
                        return 0;
                    }
                    else if ( v24 == 1 && m[v17] > m[v17 + 5] )
                    {
                      return 0;
                    }
                    ++v18;
                    v17 += 5LL;
                    result = 1;
                    if ( v18 >= 4 )
                      return result;
                  }
                }
              }
            }
          }
          return 0;
        }
      }
      return 0;
    }
    

    可以看出f(x)函数是先对m数组的值判断,如果当前值不是0,判断输入的值是不是0,如果不是,则退出,即代表输入错误,如果当前m值是0,判断输入值是0,则退出,代表输入错误,如果不是,则把输入值赋值给m数组当前值.可以得出输入的第13和第19位为0c()函数是对赋值后的m数组校验,先是判断相邻数字横向大小,再判断竖向,可以据此写出z3脚本求解:

    
    from z3 import *
    x1 = Int('x1')
    x2 = Int('x2')
    x3 = Int('x3')
    x4 = Int('x4')
    x5 = Int('x5')
    x6 = Int('x6')
    x7 = Int('x7')
    x8 = Int('x8')
    x9 = Int('x9')
    x10 = Int('x10')
    x11 = Int('x11')
    x12 = Int('x12')
    x13 = Int('x13')
    x14 = Int('x14')
    x15 = Int('x15')
    x16 = Int('x16')
    x17 = Int('x17')
    x18 = Int('x18')
    x19 = Int('x19')
    x20 = Int('x20')
    x21 = Int('x21')
    x22 = Int('x22')
    x23 = Int('x23')
    x24 = Int('x24')
    x25 = Int('x25')
    s = Solver()
    s.add(x13 == 4,x19 == 3)
    s.add(x1 < 6, x1 > 0)
    s.add(x2 < 6, x2 > 0)
    s.add(x3 < 6, x3 > 0)
    s.add(x4 < 6, x4 > 0)
    s.add(x5 < 6, x5 > 0)
    s.add(x6 < 6, x6 > 0)
    s.add(x7 < 6, x7 > 0)
    s.add(x8 < 6, x8 > 0)
    s.add(x9 < 6, x9 > 0)
    s.add(x10 < 6, x10 > 0)
    s.add(x11 < 6, x11 > 0)
    s.add(x12 < 6, x12 > 0)
    s.add(x13 < 6, x13 > 0)
    s.add(x14 < 6, x14 > 0)
    s.add(x15 < 6, x15 > 0)
    s.add(x16 < 6, x16 > 0)
    s.add(x17 < 6, x17 > 0)
    s.add(x18 < 6, x18 > 0)
    s.add(x19 < 6, x19 > 0)
    s.add(x20 < 6, x20 > 0)
    s.add(x21 < 6, x21 > 0)
    s.add(x22 < 6, x22 > 0)
    s.add(x23 < 6, x23 > 0)
    s.add(x24 < 6, x24 > 0)
    s.add(x25 < 6, x25 > 0)
    s.add(x6 > x7)
    s.add(x3 > x8)
    s.add(x4 > x5)
    s.add(x5 > x10)
    s.add(x14 > x15)
    s.add(x19 > x14)
    s.add(x23 > x24)
    s.add(x25 > x20)
    s.add(x21 > x22)
    s.add(x22 > x17)
    s.add(x12 > x11)
    s.add(x1 != x2, x1 != x3, x1 != x4, x1 != x5, x2 != x3, x2 != x4, x2 != x5, x3 != x4, x3 != x5, x4 != x5)
    s.add(x6 != x7, x6 != x8, x6 != x9, x6 != x10, x7 != x8, x7 != x9, x7 != x10, x8 != x9, x8 != x10, x9 != x10)
    s.add(x11 != x12, x11 != x13, x11 != x14, x11 != x15, x12 != x13, x21 != x14, x12 != x15, x13 != x14, x13 != x15,
          x14 != x15)
    s.add(x16 != x17, x16 != x18, x16 != x19, x16 != x20, x17 != x18, x17 != x19, x17 != x20, x18 != x19, x18 != x20,
          x19 != x20)
    s.add(x21 != x22, x21 != x23, x21 != x24, x21 != x25, x22 != x23, x22 != x24, x22 != x25, x23 != x24, x23 != x25,
          x24 != x25)
    s.add(x1 != x6, x1 != x11, x1 != x16, x1 != x21, x6 != x11, x6 != x16, x6 != x21, x11 != x16, x11 != x21, x16 != x21)
    s.add(x2 != x7, x2 != x12, x2 != x17, x2 != x22, x7 != x12, x7 != x17, x7 != x22, x12 != x17, x12 != x22, x17 != x22)
    s.add(x3 != x8, x3 != x13, x3 != x18, x3 != x23, x8 != x13, x8 != x18, x8 != x23, x13 != x18, x13 != x23, x18 != x23)
    s.add(x4 != x9, x4 != x14, x4 != x19, x4 != x24, x9 != x14, x9 != x19, x9 != x24, x14 != x19, x14 != x24, x19 != x24)
    s.add(x5 != x10, x5 != x15, x5 != x20, x5 != x25, x10 != x15, x10 != x20, x10 != x25, x15 != x20, x15 != x25,
          x20 != x25)
    if s.check() == sat:
        m = s.model()
        print(m.eval(x1),m.eval(x2),m.eval(x3),m.eval(x4),
              m.eval(x5),m.eval(x6),m.eval(x7),m.eval(x8),
              m.eval(x9),m.eval(x10),m.eval(x11),m.eval(x12),
              m.eval(x13),m.eval(x14),m.eval(x15),m.eval(x16),
              m.eval(x17),m.eval(x18),m.eval(x19),m.eval(x20),
              m.eval(x21),m.eval(x22),m.eval(x23),m.eval(x24),m.eval(x25))
    

    得到m数组值:1 4 2 5 3 5 3 1 4 2 3 5 4 2 1 2 1 5 3 4 4 2 3 1 5

    则输入值为: 1425353142350212150442315

    你做的每件事都值得。 ——yaerda
  • 相关阅读:
    windows下部署MySQL 8.0.11
    基于beego构建Restful API服务
    Go 并发
    Go语言的面向对象(OOP)
    Go基础语法纪要
    软件工程基础图式(第四章 系统设计-面向过程的系统设计)
    概率论与数理统计图式(第三章 多维随机变量)
    编译技术图式(第四章 语法分析)01文法和语法的定义
    计算机组成原理和结构图式(第三章 CPU子系统)
    Java图式(第三章 流程控制、数组)
  • 原文地址:https://www.cnblogs.com/XXX-Echoed/p/14852868.html
Copyright © 2020-2023  润新知