【综合】简单加解密——寻找序列号

【综合】简单加解密——寻找序列号

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

下面文字对你可能有用(复制+粘贴):

#include <stdlib.h>

#include <string.h>
#include “malloc.h”
#define MaxPass 66 // 最多66段密文
#define NumbPwdTable 5 // 密码表的份数
#define SizePwdTable 0x210 // 每份密码表占用字节数

struct PassStru // 密码表结构: 编移(4字节),密文长度(2字节),钥匙(1字节)。 结构体长度此处须为 4的倍数
{unsigned int Offset; unsigned short int Size; unsigned char Key; char cJiangYou;} // cJiangYou打酱油

char MsgErr[]=“Wrong Key!”,MsgSn[]="Serial No.: ",MsgMD9[]="MD9: ";

文件下载

话说这些文件被我放在我的“图床”里了哈哈哈,有人能get到我的笑点吗
VxCrp2018A1.VDF
VxCrp2018A2.VDF
VxCrp2018A3.VDF
VxCrp2018A4.VDF
VxCrp2018A5.VDF
VxCrp2018A6.VDF
VxCrp2018A7.VDF

思路

真的很简单就是按照题目模拟就行了,没有特别的,这道题的文件结构很简单也用不到KMP,所以就不多解释了

代码

#include <stdio.h>
#include <string.h>
struct key{
	unsigned int offset;
	unsigned short size;
	unsigned char K;
}table;
int main(){
	char pos[20],ciph[10000];
	int N,i,j = 1,s,m;
	scanf("%s\n%d",pos,&N);
	FILE *fp = fopen(pos,"rb");
	for(i = 0;i < 5;i++){
		fseek(fp,(N-1)*8+i*0x210,0);
		fread(&(table.offset),7,1,fp);
		fseek(fp,table.offset,0);
		fread(ciph,table.size,1,fp);
		ciph[0] += table.K;
		if(ciph[0] == 'W') continue;
		else
		{
			while(j < table.size)
			{
				ciph[j] += table.K;
				if(ciph[j] == 'e' && ciph[j - 1] == 'S') s = j - 1;
				if(ciph[j] == 'D' && ciph[j - 1] == 'M') m = j - 1;
				j ++;
			}
			break;
		}
	}
	printf("XH: %02d\n",N);
	printf("SN: %.19s\n",ciph + s + 12);
	printf("M9: %.32s\n",ciph + m + 5);
}

或者

#include <stdio.h>
#include <string.h>
struct key{
	unsigned int offset;
	unsigned short size;
	unsigned char K;
}table;
int main(){
	char pos[20],ciph[10000];
	int N,i;
	scanf("%s\n%d",pos,&N);
	FILE *fp = fopen(pos,"rb");
	for(int i = 0;i < 5;i++){
		fseek(fp,(N-1)*8+i*0x210,0);
		fread(&(table.offset),7,1,fp);
		fseek(fp,table.offset,0);
		fread(ciph,table.size,1,fp);
		for(int j = 0;j < table.size;j++) ciph[j] += table.K;
		if(!strncmp(ciph,"Wrong Key!",9)) continue;
		else break;
	}
	printf("XH: %02d\n",N);
	for(i = 0;;i++){
		if(strncmp(ciph+i,"Serial No.: ",11)==0){
			printf("SN: %.19s\n",ciph + i + 12);
			break;
		}
	}
	for(;;i++){
		if(strncmp(ciph+i,"MD9: ",4)==0){
			printf("M9: %.32s\n",ciph + i + 5);
			break;
		}
	}
}

java版

鉴于有个小朋友一直想要JAVA版,所以写了一下(java对二进制的读取是真滴难受,有大佬有好的方法请教给我)

import java.io.*;

public class Main {
  public static void main(String[] args) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String pos = reader.readLine();
    int N = Integer.parseInt(reader.readLine());
    FileInputStream fp = new FileInputStream(pos);

    byte[] ciph = null;
    int s = 0;
    int m = 0;
    for (int i = 0; i < 5; i++) {
      fp.getChannel().position((N - 1) * 8 + i * 0x210);
      DataInputStream dis = new DataInputStream(fp);
      //下面这三行就是我吐槽的地方了
      int offset = Integer.reverseBytes(dis.readInt());
      int size = dis.readUnsignedShort();
      int K = dis.readUnsignedByte();

      Key table = new Key(offset, size, K);
      fp.getChannel().position(table.offset);
      ciph = new byte[table.size];
      fp.read(ciph);
      ciph[0] += table.K;
      if (ciph[0] == 'W') continue;
      else {
        int j = 0;
        for(int t = 0; t < table.size; t ++) ciph[t] += table.K;
        while (++j < table.size){
          if (ciph[j] == 'e' && ciph[j - 1] == 'S') s = j - 1;
          if (ciph[j] == 'D' && ciph[j - 1] == 'M') m = j - 1;
          if(s != 0 && m != 0) break;//都找到就可以走了
        }
      break;
      }
    }
    fp.close();
    System.out.printf("XH: %02d\n", N);
    System.out.printf("SN: %.19s\n", new String(ciph, s + 12, 19));
    System.out.printf("M9: %.32s\n", new String(ciph, m + 5, 32));
  }
}


class Key {
  int offset;
  int size;
  int K;

  public Key(int offset, int size, int K) {
    this.offset = offset;
    this.size = size;
    this.K = K;
  }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值