哔哩哔哩稿件号转换


前几天B站官方更改了稿件号码的表示形式,许多人怀念过去的av号,那么今天我提供一个C++代码来转换av号与BV号。
算法来自知乎大佬。
代码中并没有关于算法的注释,但我想在看完 算法之后理解代码应该不会有太大问题。
我本地的文件名为 convert.cpp.
文件下载地址

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define FOR(i, a, b)  for(int i(a), i##_END_(b); i < i##_END_; i++)
typedef long long LL;
char table[] = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
int tr[1005];
int pos[] = {11, 10, 3, 8, 4, 6};
#define XORNUM 177451812
#define ADDNUM 8728348608LL
#define MODE 0//0:file_call_mode, 1:input_mode
LL Pow(int x, int a) {
	LL ans = 1;
	while(a) {
		if(a & 1) ans *= x;
		x *= x;
		a >>= 1;
	}
	return ans;
}
LL decode(char* BVnumber) {
	LL r = 0;
	for(int i = 0; i < 6; ++i) r += tr[(int)BVnumber[pos[i]]] * Pow(58, i);
	return (r - ADDNUM) ^ XORNUM;
}
char BVtemp[15] = "BV1  4 1 7  ";
char* encode(LL avnumber) {
	avnumber = (avnumber ^ XORNUM) + ADDNUM;
	static char BVnumber[15] = "BV1  4 1 7  ";
	for(int i = 0; i < 6; ++i) BVnumber[pos[i]] = table[avnumber / Pow(58, i) % 58];
	return BVnumber;
}
bool checkBV(char* BVnumber) {
	for(int i = 0; i < 12; i++)if(BVtemp[i] != 32 && BVtemp[i] != BVnumber[i]) return false;
	return true;
}
#if MODE == 0
int main(int argc, char** argv) {
#else
int main() {
#endif
#if MODE == 0
	if(argc == 1) {
		puts("EXAMPLE1: \"convert av170001\" (without quotes)");
		puts("EXAMPLE2: \"convert BV17x411w7KC\" (without quotes)");
		return 0;
	}
	FOR(id, 1, argc) {
#endif
		for(int i = 0; i < 58; ++i) tr[(int)table[i]] = i;
		LL avnumber;
#if MODE == 0
		char *number = argv[id];
#else
	char number[15];
	while(scanf("%s", number) != EOF) {
#endif
		if(number[0] == 'a' && number[1] == 'v') {
			sscanf(number, "av%lld", &avnumber);
			printf("%s is converted to %s\n", number, encode(avnumber));
		} else if(number[0] == 'B' && number[1] == 'V') {
			if(checkBV(number)) printf("%s is converted to av%lld\n", number, decode(number));
			else puts("Please check the BV number you entered.");
		}
	}
	return 0;
}

上述代码中包含了两种形式的程序。为防止有些人(我自己)看不懂,下面拆分了一下。

文件调用型
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define FOR(i, a, b)  for(int i(a), i##_END_(b); i < i##_END_; i++)
typedef long long LL;
char table[] = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
int tr[1005];
int pos[] = {11, 10, 3, 8, 4, 6};
#define XORNUM 177451812
#define ADDNUM 8728348608LL
LL Pow(int x, int a) {
	LL ans = 1;
	while(a) {
		if(a & 1) ans *= x;
		x *= x;
		a >>= 1;
	}
	return ans;
}
LL decode(char* BVnumber) {
	LL r = 0;
	for(int i = 0; i < 6; ++i) r += tr[(int)BVnumber[pos[i]]] * Pow(58, i);
	return (r - ADDNUM) ^ XORNUM;
}
char BVtemp[15] = "BV1  4 1 7  ";
char* encode(LL avnumber) {
	avnumber = (avnumber ^ XORNUM) + ADDNUM;
	static char BVnumber[15] = "BV1  4 1 7  ";
	for(int i = 0; i < 6; ++i) BVnumber[pos[i]] = table[avnumber / Pow(58, i) % 58];
	return BVnumber;
}
bool checkBV(char* BVnumber) {
	for(int i = 0; i < 12; i++)if(BVtemp[i] != 32 && BVtemp[i] != BVnumber[i]) return false;
	return true;
}
int main(int argc, char** argv) {
	if(argc == 1) {
		puts("EXAMPLE1: \"convert av170001\" (without quotes)");
		puts("EXAMPLE2: \"convert BV17x411w7KC\" (without quotes)");
		return 0;
	}
	FOR(id, 1, argc) {
		for(int i = 0; i < 58; ++i) tr[(int)table[i]] = i;
		LL avnumber;
		char *number = argv[id];
		if(number[0] == 'a' && number[1] == 'v') {
			sscanf(number, "av%lld", &avnumber);
			printf("%s is converted to %s\n", number, encode(avnumber));
		} else if(number[0] == 'B' && number[1] == 'V') {
			if(checkBV(number)) printf("%s is converted to av%lld\n", number, decode(number));
			else puts("Please check the BV number you entered.");
		}
	}
	return 0;
}
直接打开型
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define FOR(i, a, b)  for(int i(a), i##_END_(b); i < i##_END_; i++)
typedef long long LL;
char table[] = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
int tr[1005];
int pos[] = {11, 10, 3, 8, 4, 6};
#define XORNUM 177451812
#define ADDNUM 8728348608LL
LL Pow(int x, int a) {
	LL ans = 1;
	while(a) {
		if(a & 1) ans *= x;
		x *= x;
		a >>= 1;
	}
	return ans;
}
LL decode(char* BVnumber) {
	LL r = 0;
	for(int i = 0; i < 6; ++i) r += tr[(int)BVnumber[pos[i]]] * Pow(58, i);
	return (r - ADDNUM) ^ XORNUM;
}
char BVtemp[15] = "BV1  4 1 7  ";
char* encode(LL avnumber) {
	avnumber = (avnumber ^ XORNUM) + ADDNUM;
	static char BVnumber[15] = "BV1  4 1 7  ";
	for(int i = 0; i < 6; ++i) BVnumber[pos[i]] = table[avnumber / Pow(58, i) % 58];
	return BVnumber;
}
bool checkBV(char* BVnumber) {
	for(int i = 0; i < 12; i++)if(BVtemp[i] != 32 && BVtemp[i] != BVnumber[i]) return false;
	return true;
}
int main() {
	for(int i = 0; i < 58; ++i) tr[(int)table[i]] = i;
	LL avnumber;
	char number[15];
	while(scanf("%s", number) != EOF) {
		if(number[0] == 'a' && number[1] == 'v') {
			sscanf(number, "av%lld", &avnumber);
			printf("%s is converted to %s\n", number, encode(avnumber));
		} else if(number[0] == 'B' && number[1] == 'V') {
			if(checkBV(number)) printf("%s is converted to av%lld\n", number, decode(number));
			else puts("Please check the BV number you entered.");
		}
	}
	return 0;
}
发布了34 篇原创文章 · 获赞 44 · 访问量 5060

猜你喜欢

转载自blog.csdn.net/zzyyyl/article/details/105093385