LINUX.ORG.RU

Поменять в строке рандомное число на звездочку (php,perl,bash)

 , ,


0

1

Приветствую.

Имеются текстовый файл с промокодами по одному коду на строке в стоблик.

Пример:

SUQI-LUEI-3YJ4-J393-Z4RM

3JF0-XFSN-FPDY-AU7L-FBU8

Z429-WZ2L-TIYL-S4LG-04UF

Как с помощью php,perl,bash или чего то похожего, любой один символ в каждой строке поменять на звездочку *



Последнее исправление: lovelas (всего исправлений: 3)

const PATH_TO_WITH_PROMOCODES = 'i.txt';
const RESULT_FILE = 'r.txt';

$arrayOfPromos = file(PATH_TO_WITH_PROMOCODES, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($arrayOfPromos === false) {
    die('Could not read file.');
}
foreach ($arrayOfPromos as &$promocode) {
    $symbolPosition = rand(0, strlen($promocode) - 1);
    if ($promocode[$symbolPosition] === '-') {
        $symbolPosition++;
    }
    $promocode[$symbolPosition] = '*';
}
file_put_contents(RESULT_FILE, implode(PHP_EOL, $arrayOfPromos));

Вот вам кусок процедурного кода.

fernandos ★★★
()
c="SUQI-LUEI-3YJ4-J393-Z4RM"
echo ${c:0:10}*${c:11}
anonymous
()
#!/usr/bin/perl

while (<>) {
        my $offset = int (rand(length $_));
        my $ch = substr($_, $offset, 1);
        redo if $ch eq "-";
        substr($_, $offset, 1) = "*";
        print $_;
}

Запускается:

  % ./ayy.pl codes.txt                                                                                            
SUQI-LUEI-*YJ4-J393-Z4RM
3JF0-*FSN-FPDY-AU7L-FBU8
Z429-WZ2L-TIYL-S4LG-04*F

paran0id ★★★★★
()

Чтобы на всех языках уже было:

#!/bin/bash

while read line; do
    p=$(( (20*RANDOM)/32767 ))
    p=$(( p + p/4 ))
    echo ${line:0:$p}*${line:$((p+1))}
done < "$1"
xaizek ★★★★★
()
Ответ на: комментарий от xaizek

и немного статической типизации, просто чтобы было

using System;
using System.IO;
using System.Text;

namespace Development16475983
{
    class Program
    {
        static Random rnd = new Random();

        static int PickRandom(string s)
        {
            int randomCharNum = rnd.Next(0, s.Length);
            return s[randomCharNum]=='-' ? PickRandom(s) : randomCharNum;
        }

        static void Main(string[] args)
        {
            string[] promoCodes = File.ReadAllText("/tmp/promos.txt").Trim().Split("\n");
            StringBuilder promoCodesMasked = new StringBuilder();

            foreach (var pCode in promoCodes)
            {
                StringBuilder pCodeSB = new StringBuilder(pCode);
                pCodeSB[PickRandom(pCode)] = '*';
                promoCodesMasked.Append(pCodeSB);
                promoCodesMasked.Append(Environment.NewLine);
            }

            System.IO.File.WriteAllText("/tmp/promos.masked.txt", promoCodesMasked.ToString());
        }
    }
}
Ford_Focus ★★★★★
()
Ответ на: комментарий от Ford_Focus

return s[randomCharNum]==‘-’ ? PickRandom(s) : randomCharNum;

Если файле будет строка вида "----", то у коллег, которые просто прибавляли или убавляли единицу из randomCharNum, программа упадёт с исключением. В Вашем коде вначале подвиснет, а потом тоже упадёт. То есть такой код никак не защищает, а только вносит дополнительные задержки. Лучше без рекурсии.

Kogrom
()
Последнее исправление: Kogrom (всего исправлений: 1)
Ответ на: комментарий от Kogrom

Если файле будет строка вида «—-»

Статистически маловероятно.

то у коллег, которые просто прибавляли или убавляли единицу из randomCharNum, программа упадёт с исключением

Я не смотрел другие, в моём просто будет заменён минус на звёздочку, если такого индекса в строке нет, то просто строка станет чуть длиннее.

fernandos ★★★
()
Ответ на: комментарий от fernandos

Да я не к надёжности придираюсь. Если мы повторно запускаем рандом в случае попадания на тире, то код в среднем будет примерно на 15 % работать дольше, если я правильно посчитал.

Kogrom
()
Ответ на: комментарий от Kogrom
  • это PoC и он расчитан на определённый формат файла. Никаких проверок содержимого здесь нет.
  • без рекурсии лучше хотя бы из-за производительности, переписать на do-while не проблема, но опять же - это PoC
Ford_Focus ★★★★★
()
Последнее исправление: Ford_Focus (всего исправлений: 1)
Ответ на: комментарий от Ford_Focus

Дело же не именно в рекурсии, а непредсказуемом повторении подбора, если мы попадаем на тире. do-while при некорректных данных ещё хуже, так как уйдет в бесконечный цикл.

PoC

Это понятно. Я не про конкретный пример говорю, а про принцип. Мы закладываем тормоза, которые зависят от случайности. При этом есть альтернатива, в которой этого нет.

Kogrom
()
Ответ на: комментарий от Kogrom

Дело же не именно в рекурсии, а непредсказуемом повторении подбора, если мы попадаем на тире. do-while при некорректных данных ещё хуже, так как уйдет в бесконечный цикл.

Товарищ, человек банально решил конкретную проблему, вы вообще о какой непредсказуемости?

Мы закладываем тормоза, которые зависят от случайности

Вот это тормозища.

Если серьёзно, прочитайте про закон тривиальности.

fernandos ★★★
()
Ответ на: комментарий от Ford_Focus

Я пример с одними тире привёл для наглядности. Если строки соответствуют заданному шаблону, то программа просто будет в среднем работать примерно на 15% дольше. У нас 4 тире на 29 символов. То есть 4/29 = 0,1379, плюс некоторые уйдут на третий круг и т.д.

В данной конкретной программе и так сойдёт, конечно.

Kogrom
()
Ответ на: комментарий от Kogrom

ты всё неправильно посчитал - есть 15% вероятности, что рандом нам подкинет тире и нам придётся еще раз дёрнуть рандом

вызов рандома это не 15% времени работы программы, даже не близко

Ford_Focus ★★★★★
()
Ответ на: комментарий от fernandos

прочитайте про закон тривиальности

Почитал. Ребята обсуждали строительство сарая для велосипедов, вместо строительства электростанции, потому что сарай было строить проще. История интересная, но как она относится к этой теме?

Kogrom
()
Ответ на: комментарий от fernandos

Не. Они обсуждали сарай вместо того чтобы обсуждать электростанцию. А я говорю о том, что конструкция первой «электростанции» лучше конструкции второй.

Ну хорошо, допустим я обсуждаю мелочи по незнанию закона тривиальности. Но зачем это делают другие участники спора, которые знают о законе?

Kogrom
()
Ответ на: комментарий от Kogrom

Они обсуждали сарай вместо того чтобы обсуждать электростанцию.

Из-за того, что сарай зелёный, а не жёлтый.

Но зачем это делают другие участники спора, которые знают о законе

Надо же вам объяснить, что вы обсуждаете мелочи.

fernandos ★★★
()
Последнее исправление: fernandos (всего исправлений: 1)

Зачем любой? Нужно любой кроме '-' лул. Держи. Скриптота для лохов :D

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    FILE * pfin  = fopen(argv[1],"r");
    FILE * pfout = fopen(argv[2],"w");

    srand(time(NULL));

    if(!pfin || !pfout)
    {
        fprintf(stderr, "need 2 arguments input file and output file\n");
        exit(-1);
    }

    char buff[127]= {0};

    while ( fgets(buff,125,pfin) )
    {
        int a = rand() % 20 + 1;
        if(buff[a]=='-')
        { 
            a++;
        };
        buff[a]='*';
        fprintf(pfout,"%s",buff);
    }

    fclose(pfin);
    fclose(pfout);
    return 0;
}
dron@gnu:~$ gcc fff.c -o app && ./app ./a ./b ;cat b
SUQI-L*EI-3YJ4-J393-Z4RM
3JF0-XFSN-*PDY-AU7L-FBU8
Z*29-WZ2L-TIYL-S4LG-04UF
dron@gnu:~$ 

Но какой фообще смысл? Подобрать всего 1 символ сможет и Вася из 2б класса, тупо перебором лфавита и цифарок за 5 минут.

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)

Perl (труЪ-вариант):

$ perl -pe '$r = int(rand(20)); s/(\w)/--$r == 0 ? "*" : $1/ge' <input.txt
SUQI-LUEI-3YJ4-J*93-Z4RM
3JF0-XF*N-FPDY-AU7L-FBU8
Z429-WZ2L-TIYL-S4LG-*4UF

P.S. rand(20) можно поменять на rand(@{ [/\w/g] }) по вкусу.

Minoru ★★★
()
Последнее исправление: Minoru (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.