首页
社区
课程
招聘
[求助]一个算法注册机的用C语言要如何编写?
发表于: 2009-3-4 15:07 7239

[求助]一个算法注册机的用C语言要如何编写?

2009-3-4 15:07
7239
已知道关键算法是:
1.机器码为8位的字符(例如:"KFFH-TP6");
2.先把机器码的每一位的ASCII值加上循环变量的值(“F”为46+1=G);
3.把得出来的值乘于7(47*7=1F1);
4.再把积的低八位的数值强制转化成字符再除于10取余数(FFFFFFF1 (-15.)/A=FFFFFFFB (-5.))。
5.最后取“-5”的负号;
6.把的出的结果倒叙一下(“-0173--3”);

晕啊!连自己的舌头都打解了!总知都是C语言特有的运算机制,它允许字符参与运算!弄的我如此的狼狈

不堪!下面是我以下的部分代码:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h> 

int _tmain(int argc, _TCHAR* argv[])
{
    char a,b,c,d,e;  //定义5个字符型的变量;
    int i,x;     //定义2个整数型的变量;
    scanf("%c",&a);  //接受字符变量输入;
    b=a*7;  //字符变量ASCII值乘于7;
    i=b;    //字符变量强制转化成整数型;
    c=i;    //整数变量又强制转化成字符型;
    d=c%10; //字符变量ASCII值除于10取余数;
    x=d;  //字符变量强制转化成整数型;
    e=x;  //整数变量又强制转化成字符型;
    printf("%c\n%c\n%d\n%c\n%c\n%d\n%c\n%c\n%d\n%c\n",a,b,i,c,d,x,e);

    return 0;
}


现在就是不懂如何用循环来简化运算机制,还有不懂如何提取那个负号,运算后的出的注册结果:“-

0173--3”希望懂C的编程高手能指教一二!要是用别的语言来实现的话就更难了,要用的汇编也不知道能

不能做的这样的效果啊!

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (18)
雪    币: 347
活跃值: (30)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
2
用Delphi写吧,Delphi的copy()很强大的

PS:我不会写,我只会吹而已
2009-3-4 17:26
0
雪    币: 1074
活跃值: (160)
能力值: ( LV13,RANK:760 )
在线值:
发帖
回帖
粉丝
3
让我先想想……
2009-3-4 17:31
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
4
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main()
{
        char s[256] = {0};
        char sn[256] = {0};
        int i;
        char c;
        char tmp[4] = {0};
        int len;
        printf("请输入你的机器码:");
        scanf("%s",&s);
        printf("\n");
        len = strlen(s);
        for (i = 0; i < len; i++)
        {
                c = ((char)((s[i] + 1) * 7)) % 10;
                itoa(c,(char*)&tmp,10);
                c = tmp[0];
                *(unsigned long*)&tmp = 0;
                sn[len-i-1] = c;
        }
        printf("你的注册码是:%s\n",sn);
        system("pause");
        return 0;
};
2009-3-4 17:40
0
雪    币: 347
活跃值: (30)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
5
说实话,到现在我对算法都不是很明白
2009-3-4 17:41
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
6
我的代码就是按照他描述的算法写出来的,不过我试了下他给的机器码计算了一下,得到得结果和他给出的结果不同,所以也不太敢肯定这样写对不对。
  for (i = 0; i < len; i++)
  {
    c = ((char)((s[i] + 1) * 7)) % 10; // 这个计算就是他描述的将机器码每一位ASCII码加1,乘以7,将结果转换成char类型再除以10取余。
    itoa(c,(char*)&tmp,10); // 将上面得到的结果转换成字符类型,保存在tmp变量中。
    c = tmp[0]; // 取出转换后的第一个字符。如果这个字符是"-5",那么c就会等于"-"号。
    *(unsigned long*)&tmp = 0; // 将tmp变量重初始化为0进行下一轮运算。
    sn[len-i-1] = c;  // 将得到的值按倒序存入。
  }
2009-3-4 18:03
0
雪    币: 347
活跃值: (30)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
7
主要是第四步那里,我感觉楼主没有把算法描述清楚


for (i = 0; i < len; i++)
{
c = ((char)((s + i) * 7)) % 10; // 这个计算就是他描述的将机器码每一位ASCII码加1,乘以7,将结果转换成char类型再除以10取余。

// 这里应该是加i才对,因为楼主说的是加循环变量的值

itoa(c,(char*)&tmp,10); // 将上面得到的结果转换成字符类型,保存在tmp变量中。

c = tmp[0]; // 取出转换后的第一个字符。如果这个字符是"-5",那么c就会等于"-"号。

// 这样不是每次都要取吗?这样不会覆盖吗?这样算的如果是负数的话是对的,那如果是正数呢?每次都只取第一位?
*(unsigned long*)&tmp = 0; // 将tmp变量重初始化为0进行下一轮运算。

sn[len-i-1] = c; // 将得到的值按倒序存入。

// 这里这个倒序很好玩,学习了
}
2009-3-4 18:14
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
8
// 刚才没注意到是加i值的,改了之后得到的结果就和楼主给的一样了。
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main()
{
        char s[256] = {0};
        char sn[256] = {0};
        int i;
        char c;
        char tmp[4] = {0};
        int len;
        printf("请输入你的机器码:");
        scanf("%s",&s);
        printf("\n");
        len = strlen(s);
        for (i = 0; i < len; i++)
        {
                c = ((char)((s[i] + i) * 7)) % 10;
                itoa(c,(char*)&tmp,10);
                c = tmp[0];
                *(unsigned long*)&tmp = 0;
                sn[len-i-1] = c;
        }
        printf("你的注册码是:%s\n",sn);
        system("pause");
        return 0;
};
2009-3-4 18:18
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
9
// 这样不是每次都要取吗?这样不会覆盖吗?这样算的如果是负数的话是对的,那如果是正数呢?每次都只取第一位?
    *(unsigned long*)&tmp = 0; // 将tmp变量重初始化为0进行下一轮运算。
是的,每次都要取,而且也要覆盖掉,因为每次计算得到的结果都是不同的。正数也是取第一位字符的。
2009-3-4 18:19
0
雪    币: 261
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
10
谢谢小虾大侠!其实他的这个算法是有漏洞的!关键就是有内存缢出,要不然就好写了!小子贼野大大我也懂点点DELPHI不过用D要实现就难了因为涉及了低八位的运算,D的话就要加入汇编,但是那益出问题还是不能解决!
2009-3-4 19:29
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
11
delphi处理八位数据也很好处理的,并不用用到汇编。你所说的溢出是什么?
2009-3-4 19:52
0
雪    币: 1074
活跃值: (160)
能力值: ( LV13,RANK:760 )
在线值:
发帖
回帖
粉丝
12
嗯,这段代码写得比较精练,我还在想什么意思呢...
2009-3-4 20:32
0
雪    币: 261
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
13
是吗?"-5"不是溢出造成的吗?低八位明明是F1/A=18,结果经是"-5"晕透了!
2009-3-4 21:36
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
14
0xF1按有符号数来看就是-15,-15 % 10 = -5 没错,并不属于溢出。
2009-3-4 21:50
0
雪    币: 261
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
呵呵!强顶一下!
2009-3-4 22:26
0
雪    币: 347
活跃值: (30)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
16
这个算法很有意思,至少我是这么认为的

小虾老大给的代码已经和你的结果一样了呀,难道注册还是不行吗?

这个算法我是不懂,我用Delphi也写不出来,用C写还是看了小虾老大以后的才理解的

个人认为你没描述清楚算法,我按照我的理解和小虾老大写的代码写了一下我的理解

1、取机器码的Ascii,记为szAscii,然后让c = (char)((s[i]+i)*7) % 10;
     这里的(char)是把数字转为字符;
2、再让temp = (char)c,因为C语言不允许这么做,所以就要用到itoa这个函数,
   写成C就是这样的:itoa(c,(char *)&temp,10),参数不懂的自己百度
3、然后在让c = temp[0];也就是说取第一位,然后把temp[0]清零;
4、把c倒序在sn的最后一位,也就是倒序,sn[len - i - 1] = c;//这个倒序很好玩,值得我学习

我不明白你写的第四步是什么意思,但是小虾老大写的代码发出来以后我才明白你写的第四步其实就是要取求余以后的第一个字符

以上完全是我的个人理解,如果不对的话请指出错在哪里,谢谢

PS:由于我学艺不精,所以不能帮你解决问题,我只能说到这了,不好意思
2009-3-4 22:48
0
雪    币: 1074
活跃值: (160)
能力值: ( LV13,RANK:760 )
在线值:
发帖
回帖
粉丝
17
化繁为简:
   其实char也相当于整型 ,只不过只有1 byte,所以直接(char)某数就相当于截取其低8位,上面的表达式也就是将结果转成字串逆序输出,正数直接输,负数只输个负号。
2009-3-5 08:21
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
18
我给你的代码虽然和你的程序不同,但应该已经可以得到正确的答案了吧,只要计算方法流程结果一样,代码相不相同应该没什么关系了。
2009-3-5 09:41
0
雪    币: 261
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
19
呵呵!是我错了,我回再努力学习C的了谢谢指教!
2009-3-5 15:25
0
游客
登录 | 注册 方可回帖
返回
//