平台:多平台是首选,但我现在正在寻找任何东西。
语言:C是首选,但我应该能够翻译其他语言。
我正在编写一个程序,使用替换密码加密明文我试图计算的总数,因为缺乏一个更好的术语“cypher”排列我的意思是,我想计算所有可能的排列,它们不能代替明文本身。意思是00000000(空)不能被替换为00000000(空)我知道我可以用下面的方法生成一个n大小的块的所有可能的置换。
n(size)=3(1,2,3是正在排列的唯一值)
123个
213个
二百三十一
三百二十一
312个
一百三十二
123个
问题是,只有231和312不能将明文本身替换为明文我可以使用条件语句来确定置换是否有效,但我更喜欢一种仅计算有效置换的方法我希望已经有一个简单的方法来做到这一点,但我不知道如何文字的问题,以便谷歌它。因此,为了总结我的问题,我需要一种有效的方法来计算所有可能的cypher置换,而这些置换不会让明文无法替代。
下面的代码将为n个唯一值生成所有可能的置换但只有当n!可使用普通整数数据类型表示。
#include <stdlib.h>
#include <stdio.h>
int main()
{
int current_perm = 0;
int num_perms = 1;
int cypher_size = 0;
int buffer = 0;
int *cypher = NULL;
printf("Input the number of unique values in the cypher(The cypher's size) : ");
scanf("%i", &cypher_size);
if((cypher = malloc(sizeof(int)*(cypher_size+1))) == NULL)
{
perror("ERROR: Failed to allocate memory for the cypher ");
return 1;
}
int i = cypher_size;
int j = 0;
while(i > 0)
{
cypher[i-1] = i;
num_perms *= i;
i--;
}
for(j = 0; j < cypher_size; j++) {printf("%i ", cypher[j]);}
printf("\n");
for(current_perm = 1; current_perm < num_perms;)
{
for(i = 0; i < cypher_size-1; i++, current_perm++)
{
buffer = cypher[i+1];
cypher[i+1] = cypher[i];
cypher[i] = buffer;
for(j = 0; j < cypher_size; j++) {printf("%i ", cypher[j]);}
printf("\n");
}
}
}
最佳答案
没有固定点的置换称为derangements下面的c代码使用来自wikipedia链接的交替求和公式。
static int nder(int n) {
int m = 1;
int f = 1;
for (int k = n; k > 0; k--) {
f *= k;
m = f - m;
}
return m;
}
你可以把整数换成大数或双数在后一种情况下,你应该得到一个精确的答案。如果答案不符合双倍,ln(n!/e)=ln(1)+ln(2)++Ln(n)-1=cc>如果在
lgamma(n + 1.0) - 1.0
中可用lgamma
,则是错乱数的自然对数的一个很好的近似值。关于c - 计算完全替代的密码置换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17689318/