C 中的正则表达式 - 搜索信用卡号 - PCI 合规性 [英] Regex in C - search for credit card numbers - PCI compliance

查看:63
本文介绍了C 中的正则表达式 - 搜索信用卡号 - PCI 合规性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我需要满足客户对 PCI 的特定需求.我在 C 中相当舒服,我真的不想在这里重做轮子.我在 python 中有一个正则表达式示例,我想在 C 中应用它.

Hey guys I am needing to meet a certain client demand for PCI . I am fairly comfortable in C and I really don't want to redo the wheel here. I have an regex example in python that I would like to have applied in C.

  pan_regexs = {'Mastercard': re.compile('(?:\D|^)(5[1-5][0-9]{2}(?:\ |\-|)[0-9]{4}(?:\ |\-|)[0-9]{4}(?:\ |\-|)[0-9]{4})(?:\D|$)'), \
                  'Visa': re.compile('(?:\D|^)(4[0-9]{3}(?:\ |\-|)[0-9]{4}(?:\ |\-|)[0-9]{4}(?:\ |\-|)[0-9]{4})(?:\D|$)'), \
                  'AMEX': re.compile('(?:\D|^)((?:34|37)[0-9]{2}(?:\ |\-|)[0-9]{6}(?:\ |\-|)[0-9]{5})(?:\D|$)')}

我发现了一些 POSIX 库regex.h",这似乎使用了非常古老的正则表达式标准.

I have found some POSIX library "regex.h " and this seems to used the really old regex standard.

我发现了两个示例,其中一个使用 POSIX 正则表达式,但充其量似乎受到限制.从此处

I have found two examples one uses POSIX regex which seems to be limited at best. Stolen from Here

#include <regex.h>        
regex_t regex;
int reti;
char msgbuf[100];

/* Compile regular expression */
reti = regcomp(&regex, "^a[[:alnum:]]", 0);
if (reti) {
    fprintf(stderr, "Could not compile regex\n");
    exit(1);
}

/* Execute regular expression */
reti = regexec(&regex, "abc", 0, NULL, 0);
if (!reti) {
    puts("Match");
}
else if (reti == REG_NOMATCH) {
    puts("No match");
}
else {
    regerror(reti, &regex, msgbuf, sizeof(msgbuf));
    fprintf(stderr, "Regex match failed: %s\n", msgbuf);
    exit(1);
}

/* Free memory allocated to the pattern buffer by regcomp() */
regfree(&regex);

我在上面看到的问题是它使用(从我收集到的)旧正则表达式,它不支持删除空格和破折号.它似乎也只是真的执行了一些匹配并为此寻找合适的例子是在谷歌中没有为我带来很多结果.所以我进一步看了一下,在那个答案中(上面的问题)提到了 PCRE 的使用.

The problem I see with the above is that it uses (from what I have gathered) Old Regex which doesn't support removing spaces and dashes.It also only really seems to perform some matching and looking for decent examples for this is not been turning many results for me in Google. So I looked further and in that answer it ( the question above) mentions the use of PCRE.

我在这里

正如我之前所说,我不想重新发明轮子.我认为在可能存在干净和简单的东西时,为可能包含潜在缺陷的内容编写自己的正则表达式会很糟糕.

As I said before, I don't want to reinvent the wheel . I think it would be terrible to write my own regex for what could contain potential flaws when something clean and simple probably exists.

PCI 问题来自一个客户,我们需要能够监控系统以了解它们如何/在哪里存储 PAN 等.这有点像 DLP,审计范围,并证明 CCNS 存储正确.

The PCI question comes from a client that we need to be able to monitor systems for how/where they are storing PANs and such. It's sort of a DLP, sphere of audit,and proving that CCNS are stored correctly.

如何在 C 中使用正则表达式来搜索信用卡号?

How can I use regex in C to search for credit card numbers?

附注.我对这个正则表达式没问题,并愿意以更好的方式来做这个正则表达式.

PS. I am ok with this regex, and open for better ways of doing this regex.

推荐答案

好的,我最终使用了 PCRE2,而且效果非常好.

Ok I ended up using PCRE2 and it works remarkably well.

我想我在 Github 上看到的源代码,但它也在 这里.

The source code I think I saw on Github, but it's is also Here too.

我下载了它,编译了它,然后安装了它.做以下..请记住,有一个 8,16 和 32 位格式.我看到的所有示例都使用了 8 位,我发现它最适合我正在做的事情.

I downloaded it, compiled it , and installed it. Doing the following.. Keep in mind there is an 8,16,and a 32 bit formatting for this. All the examples I saw used the 8 bit and I found that it worked best for what I was doing.

./configure --enable-pcre2-8
make
make install

我还必须使其生成的库可通过使用链接进行搜索.

I had to also make the libraries it produces searchable by the linked by using.

ldconfig

当然,当您编译程序时,您需要将程序链接到库.如果您使用这些版本,则使用 -lpcre2-8 库将被命名为 pcre2-16 、 pcre2-32 .

Of course when you're compiling your program you need to link your program to the library. using -lpcre2-8 the library will be named pcre2-16 , pcre2-32 if you're using these versions.

之后我使用

cc -Wall pcre2demo.c -lpcre2-8 -o pcre2demo

如果你不想阅读他们在他们巨大的例子中写的所有东西,我自己做了......警告我现在正在将它与一些功能分开,所以你可能想要仔细检查问题.不过,我将提供的示例确实有效.

If you don't want to read all the things that they wrote in their gigantic example, I made my own... Warning I am stripping this apart from a few functions right now so you might want to double check for problems. The example I will provide does work however.

// YOU MUST SPECIFY THE UNIT WIDTH BEFORE THE INCLUDE OF THE pcre.h

#define PCRE2_CODE_UNIT_WIDTH 8
#include <stdio.h>
#include <string.h>
#include <pcre2.h>
#include <stdbool.h>

int main(){

bool Debug = true;
bool Found = false;
pcre2_code *re;
PCRE2_SPTR pattern;
PCRE2_SPTR subject;
int errornumber;
int i;
int rc;
PCRE2_SIZE erroroffset;
PCRE2_SIZE *ovector;
size_t subject_length;
pcre2_match_data *match_data;


char * RegexStr = "(?:\\D|^)(5[1-5][0-9]{2}(?:\\ |\\-|)[0-9]{4}(?:\\ |\\-|)[0-9]{4}(?:\\ |\\-|)[0-9]{4})(?:\\D|$)";
char * source = "5111 2222 3333 4444";

pattern = (PCRE2_SPTR)RegexStr;// <<<<< This is where you pass your REGEX 
subject = (PCRE2_SPTR)source;// <<<<< This is where you pass your bufer that will be checked. 
subject_length = strlen((char *)subject);




  re = pcre2_compile(
  pattern,               /* the pattern */
  PCRE2_ZERO_TERMINATED, /* indicates pattern is zero-terminated */
  0,                     /* default options */
  &errornumber,          /* for error number */
  &erroroffset,          /* for error offset */
  NULL);                 /* use default compile context */

/* Compilation failed: print the error message and exit. */
if (re == NULL)
  {
  PCRE2_UCHAR buffer[256];
  pcre2_get_error_message(errornumber, buffer, sizeof(buffer));
  printf("PCRE2 compilation failed at offset %d: %s\n", (int)erroroffset,buffer);
  return 1;
  }


match_data = pcre2_match_data_create_from_pattern(re, NULL);

rc = pcre2_match(
  re,
  subject,              /* the subject string */
  subject_length,       /* the length of the subject */
  0,                    /* start at offset 0 in the subject */
  0,                    /* default options */
  match_data,           /* block for storing the result */
  NULL);

if (rc < 0)
  {
  switch(rc)
    {
    case PCRE2_ERROR_NOMATCH: //printf("No match\n"); //
    pcre2_match_data_free(match_data);
    pcre2_code_free(re);
    Found = 0;
    return Found;
    //  break;
    /*
    Handle other special cases if you like
    */
    default: printf("Matching error %d\n", rc); //break;
    }
  pcre2_match_data_free(match_data);   /* Release memory used for the match */
  pcre2_code_free(re);
  Found = 0;                /* data and the compiled pattern. */
  return Found;
  }


if (Debug){
ovector = pcre2_get_ovector_pointer(match_data);
printf("Match succeeded at offset %d\n", (int)ovector[0]);

if (rc == 0)
  printf("ovector was not big enough for all the captured substrings\n");


if (ovector[0] > ovector[1])
  {
  printf("\\K was used in an assertion to set the match start after its end.\n"
    "From end to start the match was: %.*s\n", (int)(ovector[0] - ovector[1]),
      (char *)(subject + ovector[1]));
  printf("Run abandoned\n");
  pcre2_match_data_free(match_data);
  pcre2_code_free(re);
  return 0;
}

for (i = 0; i < rc; i++)
  {
  PCRE2_SPTR substring_start = subject + ovector[2*i];
  size_t substring_length = ovector[2*i+1] - ovector[2*i];
  printf("%2d: %.*s\n", i, (int)substring_length, (char *)substring_start);
  }
}

else{
  if(rc > 0){
    Found = true;

    } 
} 
pcre2_match_data_free(match_data);
pcre2_code_free(re);
return Found;

}

这篇关于C 中的正则表达式 - 搜索信用卡号 - PCI 合规性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆