From 6c1121e1d407e067d1b75d019182ab03dfb22ed4 Mon Sep 17 00:00:00 2001 From: anakod Date: Thu, 24 Nov 2022 01:29:53 +0500 Subject: [PATCH] MVP version :) --- .clang-format | 191 ++++++++++++++++++++++++++++ .editorconfig | 13 ++ .gitignore | 2 + README.md | 4 +- application.fam | 12 ++ icons/Horizontal_arrow_9x7.png | Bin 0 -> 1479 bytes icons/Ok_btn_9x9.png | Bin 0 -> 3605 bytes icons/Pin_back_arrow_10x8.png | Bin 0 -> 3606 bytes icons/Vertical_arrow_7x9.png | Bin 0 -> 1482 bytes icons/passgen_icon.png | Bin 0 -> 173 bytes images/preview.png | Bin 0 -> 980 bytes passgen.c | 220 +++++++++++++++++++++++++++++++++ 12 files changed, 441 insertions(+), 1 deletion(-) create mode 100644 .clang-format create mode 100644 .editorconfig create mode 100644 application.fam create mode 100644 icons/Horizontal_arrow_9x7.png create mode 100644 icons/Ok_btn_9x9.png create mode 100644 icons/Pin_back_arrow_10x8.png create mode 100644 icons/Vertical_arrow_7x9.png create mode 100644 icons/passgen_icon.png create mode 100644 images/preview.png create mode 100644 passgen.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..4b76f7f --- /dev/null +++ b/.clang-format @@ -0,0 +1,191 @@ +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: AlwaysBreak +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - __capability +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: false +ColumnLimit: 99 +CommentPragmas: '^ IWYU pragma:' +QualifierAlignment: Leave +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +PackConstructorInitializers: BinPack +BasedOnStyle: '' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +AllowAllConstructorInitializersOnNextLine: true +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 4 +IndentWrappedFunctionNames: true +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 10 +PenaltyBreakBeforeFirstCallParameter: 30 +PenaltyBreakComment: 10 +PenaltyBreakFirstLessLess: 0 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 10 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 100 +PenaltyReturnTypeOnItsOwnLine: 60 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Left +PPIndentWidth: -1 +ReferenceAlignment: Pointer +ReflowComments: false +RemoveBracesLLVM: false +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: Never +SortJavaStaticImport: Before +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: Never +SpaceBeforeParensOptions: + AfterControlStatements: false + AfterForeachMacros: false + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: false + AfterOverloadedOperator: false + BeforeNonEmptyParentheses: false +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: c++03 +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a31ef8e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 + +[*.{cpp,h,c,py,sh}] +indent_style = space +indent_size = 4 + +[{Makefile,*.mk}] +indent_size = tab diff --git a/.gitignore b/.gitignore index c6127b3..9bf2d4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +dist/ + # Prerequisites *.d diff --git a/README.md b/README.md index b94d48d..fbeb416 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # flipper_passgen -Flipper Zero Password Generator +This is a simple Password Generator plugin (**fap**) for the [Flipper Zero](https://www.flipperzero.one). + +![preview](images/preview.png) \ No newline at end of file diff --git a/application.fam b/application.fam new file mode 100644 index 0000000..89b7b9d --- /dev/null +++ b/application.fam @@ -0,0 +1,12 @@ +App( + appid="passgen", + name="Password Generator", + apptype=FlipperAppType.PLUGIN, + entry_point="passgenapp", + requires=[ + "gui", + ], + fap_category="Tools", + fap_icon="icons/passgen_icon.png", + fap_icon_assets="icons", +) \ No newline at end of file diff --git a/icons/Horizontal_arrow_9x7.png b/icons/Horizontal_arrow_9x7.png new file mode 100644 index 0000000000000000000000000000000000000000..caca887186695e1da342df00e85ff3f22054dcda GIT binary patch literal 1479 zcmbVMOKj9e7fw#Uw9H#@>a%R0?&h0`cmi6HfmS$n)YitRD> zEW62p1DC2TfKijo`!Mo&;j^Az0ui%X)0S^IiuYA>G-d(d8<=%Yl`yywYUGG z`(ZzwG|p#=a^%N+OkJNl@}8pXKgwI1a??FaJQ3;C7j32wq6E;2a%yRiP;Z+_)MgzX z+v;yW?5T+Rwt8;C#con(UEbJD*~ac_%iG=ds=m5(8l4&tAc&ZxXb^>QMh3PzzQ>8_!=NEs^YSo1KpP^GGyIj$u}-RRddwWodxWvYlAcffi>cCkzhDyp$)B zix}mMv@LqlRzcH|2~kqe#@X0S;4ouA6T{STZqg9wdj&4(rQuMx?-?v)5sPI8ShK)_ zmt41izmPVH3UnryFM>v6+g^yyT003d)>$TcsmGQtg2a;(#geX&BI}Bm*il>;)+D5! zGAc#d5+a-gYHh-TEK|48>^UC$qMv=3OBp|44wcMSA!??EO>N$6;R;!>h-uE5m|#4D zx{wDxmGr-Xh0lYX*Ft@d1R{+nc!@`}!;B>E45hg)X~vnPvB#Q@t%9mL=RN@yOBF9z z)T-F0T2LwZTD!8is0HO;x(G$; z3Lm^|s_5_YX1%_aihzf3;RuOVD376fKFD)?m}{iLGYII;xN0`oh4CunXqaAvdU*xd zs+WhJ`Re$Xzp?j5wEZpv(pRL!2$qRJ_G!v$9q{yPQ_cY8jl5Pzb{PLQad`KSx}LzH zS>(&2OTnh-b1a7DmO>YM_}OJD$aK0bym%#uaXpT2Gcd#)x2azcxAABGV0BC)Aj-lw(6)B^^6`Y8RS?}DV z%)ko(See1!Eb3M$dL6)A6csaRjExg?k&xVzi*Rm;?iNJk#f=mkVEUR~jXN3dd|Lmz z;y}sMh%ol-?E1&`>dD;6jdps6NYoxN)s%@sf4~40YY6LAOtMEbwA4g#OCpANL823^ zSH66W05Hcxr$tg98gFntAOYL}xm$C;Skv&Ym?{TVR{)d(41vWacX1`7fM!jnW(lBK z26*WB#9I(Z1Ast!xEUC@Cj`v=urcBTdP`FWq=DYTy`}s>0vC{VzHdNRvxNFy}ir1|g=xDsrFP&l1P<-Sv zXLqYVYz{b^ZIV@1Ulg->7DEgvM*Min&Y8{8QW! z$_pA434?^wCTq$4%^>Zo8&|8XwbCv;KEd;WJJ{s;T}8R8Zwi7ssk$QWQ5l5+opKfX z;8D*COFEB#4W^*FIrRU%PDSc?B(}+9ZV?N9(yH>0uSnM?xg!>+>;e z{{7tXQQ|ZFXD*7q3XD!pwnih-=66+Qlqtl9;N-D|PHoI&B5d8>^V#i{mE>V0gQgu3+(DG%B z|8W!pl$lbQERt-0eZA%NSfvE4F>VAYP`DpeoF;Zm4`)2id;6xgSysWl6K$pWANcRZ z!ETRXKIU9G=@9lEB?<{ivj7!8FE9WN;qoo2Lr0#c@DmcF=JzU<73PmM3 zbe!-gs`c26Uc(AKz7%U!a0yZ5gsprdo1i51MjJPeHtV6d@Jy=*+_3dJ^>}p#8N#kPK_4t?hltq>u=?m+t z?em(Y%u3Bp_pyV?c_w-4c}p+?Y$aHr>TuPGs@SUj;Er!b@3GVLDS@T8OTts1JFS-p zKZ=&5zp;DRor*`Gy8MTeWdpVJv2(4-*slRM@XXG+i^F&Ku>7i08vKenZHoS4s(!!h zJE}*MHu7PR_IfdNzu*P}3^87K?f&A1;>NMsgKcR6**;aB74NC7tR(NB?{dHT-9QhXa*KoG!kGU1}$l2D>ypo)fSBuG$ zkTW4?+|I1m?6ZH8tD4^fB{cUpoEoZOo%4hl!EtNtQ#?j*jJR)x-Mn0TrxrX2uT_rh ziOh=Jxsktqbd9x{^s{c5z92Pk$LGoQl53o+=7QXXCp-Z>io998w|DCCCGfr20oiRN zX|`KH$W4)wN~)J$kYB~>4EU;NcS^qH&yzeUzXokpMegg_lX$6ve^4}%bY~Sg)%uJ- zZpb$p4x^GS5d{XJP=STbfpHV`58UBH& zKFg&BgS6bV+#-|^KBGeIBee2B zrM-`uTB^_(eS+{-KK1h3l`-Yjpv8X4z*uBwQ3a~pL0Ae2xvNGyC3A|#MARToe$W~8 z+4{DsyenENye9df1M}gNUM9_Leh6G=`9exL-cdSKQ_CGyEdZ3W5uoR!Lb^D)9!bd=7h@R=M%=|JqX9XP;Z6# zFD15Bw7qTP(ZlG?o@#x@=wG;XxM(>n@4P$9WwY#lW$h=`zMi_zq30HbV-zHheqpE0 zR6kXtxdzl&Ml2D#zDIvflJkb*e zIAI?GMjp?JBK76WW`{l{pFAY|%5?nYUxRnT&y6~Kz19AD;C0(z*7?dM{%HhVtqWEc z%+M$z6u@uQu)kg_%2PO_U|n1JE0V1>iVbekOLEOG$U6X^Umc519WC)L$t%`#Di0$ zY1|5H*440_`onhmXeayq`8EIg?x2r9KWe()q}QayqCMEC?c4meb4}#i`HHPaxO&3SPtSVKj@ND?Y+-@R`CDnf-d`T>vTn8RR<=@3 zNXk=Gloyh#S@3R89WHrXBHr;f(&ZO@I_Uo7;O5Bs@ecGx@7%7{_>Q`Adg&sCeZTYp ztVy{^vAUfOpTDzF*4`h%X0odWn`#uZ4s4igIV^UrVVg?c*{>K)hHq^^RxU2CM;WN> z;oK@^sg`J}BguyvilN{DQ*V+N4rD{X_~KAFj5qyk3(gP#cvSIDXe!zk3B!^InwV{j zCXGPmumQl(m`28618`K37tR+?goD{H>cAkpHyrG$XA89@o8$cOh%gGyG0e^h8y0{y z@CF+jfedLdjsO8i#eispKw=P#1_%GG3**eU%@8o?ZwNI24*pM2Xj=!6If;S;9nsX% zz(S!=&=CVoZ;TfP>*b{m(uQhlL7=)2EnN*L6sBVU)71t2^ME<-DBeCWl!etl&NwSL z*pEsj!yu5*&``}#9ZeF&7oufgU;u$?L$tLuI0%g(I+2Q@X%K^ye=Atvg0K`knTjV7 zLEDNLFH$fS4(5dVpED51|H=}B{>c+3V-OmK4AIhrZlCEl(AM_T0=zuK- zizjYd4*pHCwT0ObgQyrH7H4At2XjO;@px~TsgAA%R9|05PuEIcOUu&SOwUTs^00xK zshI`T;)sF%Z>|Li8%)3vslU12|K;lbk-Oav1Tx371&)Fb!FgLzNCeQ|r-tGG9E;W; z_5R^{|2Y=zKXM_QU?AJI{a>~IZQ?Z0_VnM@OBBhHB}+m>LbCLY=Y4wK?~kwVKJMeb&hxs?-|t+n40QpA+b4G8*k_>A)gsvzul2%)`{+ zGXO-B3u=_{$d$PU5YEZSn%Bo%6nB$X*pi8HtvlN(j>)<>oU^ms-{SJc!?CVM_kGpq zD|mb=fG|Jac@dmEE>EYKyFP!dPw~V2q0~L3V4zJ7VgZs-lDyFoU9CnK9lA z{|)s3FeAcdMKT|ltq9$x0m1;iQ-6nS!_cqj3MXxM0Gt2}LS)A!gg7{$QQxIe9%xhs z9ymYp6$g?4Aeep95(3@bioPky5s{%vM(c>C~+;D?q3rCl<9Vk3~u)C^5I%(w`)RT2PH zm)f7N?K9(ykBtnC`Hctjzt`uk1dC{xK3DmG+T--QM)Dliz9M@cHh&jC)x2t{F@ZnKih0C+}OXW@w z`v&$?T!Pj1rsQGSiPMN#jg(cf#BeEqd)~3u;mM}Qyx`i%uR_AH()f-rz&vtJ?~1BK z0wCjWh+r=QKw`~Oyt$4L(2|<}2>>cTD<8d+q=bD10syO=GrJ#HY?6E~&#jfte6C(u zt0YX=Xk{+Bqt-;ma^pzUR`Hw4DHbX&wa9MK#}7nQbGD=p$&@~a?~@uIls$T8lCHGT zTRHoMa^-n3QHw^99AP{1;ufE{Zb&OgDJ@PELckbai^>O2T$Dcqsc&TD3l~}jCU{~r zzv(gLjjtXx|H*H&$^=ebjw433!=?SMd>|aXa>3gB5?)oiL6JC$H*$+NBC6x}hAF7kW)t|J z9m26ua#NsV=VV?4pXG3D@mM_ij@FcBscZ$vT`c+>{Ka38#5<0qS`o5Kbu1s`Lk`}C ztNnHRw(Z$k$NrL*^Gd|*kZ!s*;vl|Vi-WL}unWTUV)XKz^G!Qs$eCE}Ne-py;|QoE ziVIFnDC2DAI9^+BdO1=ikF38qj1|k>fy+;lJzzvK8x_5E17Vq#bN5h7VfH)F-HXT@ zhwUgiVNOuz3x#rqq3K#J8H#9LzFuDEn{={2c`*Pw!K@JLkKSgT`X;p_=<}wD@rmf~ z;gVA4rJ@@!K08%{R8FWAD3_@~)3CQUyiHAObb-A`sHOQ|-+Z0sir>Ak`=mm`YuRLE zvRiUw^7vgB*AQ2;PWD|1mwT?8?;UeHb=$`Ek<+I_v3H91It$fZpB3&YZpDS;;+@(K zdF54mt)Bf!lqxwNW0P|pljlM#d!=%9yW%SZX%=tU#c&gu)D60B?{lPNX$l**VOcE< zdIIZ=4!P^c^-J)}8av)1B>n2);EeHy%mc04Tcui0=!xi=={@WUEb=RgEZW->(No>y zGtHP*oSy9AhtjjmvvjlOkrd=&s943GibEAK6}_QtUrgT;C)pEX^RMTnC;HoM=PBRw z=9RwiyZG%Idtrv4Jsg!__&(xHGl%#&=sLN)edgTIoh`h8iiEm=ymq_1zsj}0Uhw~9 z#8NW#s4ujm8iU4JvG{?xr?d;JWxCeN2BzQy;MMf~vb=1*A#83ixqIOEV` zVaGg#~3WwEx!kV?Q+q$;Ioo@pT$VAd^FJUK|pMWk7 z+6G@N*C4B;DJ`9n-?bZYSO3eQQfKCI=Av#Fcf@1azbbAvzVOP^{k?%t7-9b0z+hZ3 zaVn!cs{C&G8PM z+2JN0Mjo7#`(m!krk0qEMuRP#pvsP;1yp-=xo_t(VjQijbFbzedRSI|z~tIkmRs_| zzW)8E&_4stJKBW4G7xjb>97-2u07S9vv;%V`p9kjaQuUwaZ+YdW*$z8oKmXu9#*!q z%+XIrCsAsIJw|!0mU!Xy;)v!_$Xu^Na16FRuM}78B&~>r-qB$lQ9i;d$5deszcU!{ zTl=!4DREZuWEJOuQ~85O-Q_Hg*+EE+^)p4ySZAeheYhvC!k0y!={Us;;FYATIt}A- zuHORLec$46(H*yLp>@u>8zvVfHSws$-w!_}DiD%=UHO5jok!eG?^a6o;?lWyihn$? zDIXhlckt>wInSo_^n5%}_Ii2}Gnqe0E+&@qiXwmuR{ESqQ+U(U)H80A6kIb79 zf%9=Kr7f>pM2rYV(?^=0aC^Vq+>^Huk#*XW=eAmOudMomc28GLfB11cI@{U7;B zQ-8QzAye z?YX)QgQSmUMA3ROrqjb8(+}^Keqk~C{I7xACr^BG`h2tXW#7w|fwa?Q^Pou#Tc-nA z6Ux=gqvW7&R`EYy$;(ndrfyqZ_A8PP|3nOJFp782&dJ(|nq3+>oA{}~w;(&q!3^~- zt&hEkT}cb_JmgvBk8aC0Q(}I_mU%5U&3zn?_nfJue}^pk^lFtIEJ78dY$NHbLzw$V zXp^Kx-n6?(G4s3qJ66M%C`$TCPDSu}Lmjrwww;{p%X+9*d9fjae!jTBR?Bh)&695p|Np`_A@%C6Gkw(!c ztlQ|bD0BfD08GqSbOJGm#02}0{K-@lg#WAt0w(*SAnr!?Fncs1cZ-)AAzU~M!*noC|vOF)r0RvA`FmlWAHx@MBtF&>xaZy+5F>9 zprIfEOeP%(g@%WR>xUcY(-{6xxUsP@6o!Bz5PAX&y%08)Nnq(wLo|OgSdl`A3^JWb zrcuG`j07KAC=&${1pA*XDD;16sUiPVN>DQ>i$I6M^|Nl)Xlz**5m^jjZ zpQ#thS=L9?WiG40+mRzvqC`xB>H5sFVffs4KqX-!S)&$7{TGz=zWF=INHY2 z0tT}-KpPtw|HfL;h@lh`mH8X%`(G^lkJ$BrpwI=Ltw;=V7|GX$L8E~G&KgPnV=RW& zf8_fI>-)!83~m01g$ja!uJ`tT_4@agV1U-ee}`9~{5$?6s$k|Bg5ln!QST+V7#p3i zF4n&y*YC(C3v7{K(X_L&aAEcMczb*MMhV&2h)M`^tW<_XOB8+kL0OWLfY3%j)E-d2 TFC+3}9cE|kU{!4CefEC<&8td2 literal 0 HcmV?d00001 diff --git a/icons/Vertical_arrow_7x9.png b/icons/Vertical_arrow_7x9.png new file mode 100644 index 0000000000000000000000000000000000000000..b889fc8f3c320807b9c39cc66a8592e4d93b6c39 GIT binary patch literal 1482 zcmbVM%d6B@7>}T>-lE`EMGmnA?QN2iIM1W0%$?lFP;)!IcktepE_x<8nK|4fCr!>c zGncv%q1cU3Xjg?&x-2L{!9^F{v`cNfa@$Q2p{4(TXur%OO0jAUoSfJ1{J!^hwY|Q2 zaN)>;q9_MjYt9DDufjO6{}uQ@+^&2J)1GW&bxFB?=h%JN?Cmw&hN9fO_SyrwFGnV8 z?`Mi~=%;+_`C{?VQAOEzn0L12wtJp~ zMDEyXBNvFa-8O29l%a}_H4kG8RqMK0DU~YtEo5N}8@OzkmS$E6E)lbeW}gbuQa>OY z&dN*{>}<6!WkL*NI2`K3)4E7|hFP!I4Qv^fr2#_A#<8R$EzVBN861{*DNiI9G0GWf zR}7@Bf~HdwqNJdWvzeQ~VaA9ihNx=)eqqr`tNk}tgREo4C zL^uyrd(MI^Q@7B`Egt(~n4QX{%pNd@N@lANHB-Z;cG~RVDk)pUG#5=wFrGqP$OE5B z`eI<=^I-g3sPBIF5ej(w^H z)snAutF@XIRDyCnpt#ztO|^yhj_?L~1n2Ml|M~viltTs4@a1`m2$7};Md}J4ylkrI z@p-G+Y^NgNAzU~@qE*UcsGc|S9G~PGS>qW5bUdq?P4@9@6>>C5FG9V%0&LaGL(hD5 zcFbSedsEtBp8@GJQeq0rL?DMWWsM$q`nf4*fbvFOt5Z9Sf15bDd!nxAaA+3!vglH< zDf%3Xp}D2d#eV(pMhG2nspT{}CpRx$ySkvD{moksAASAK&x_w2zf!w*_?GhN>mPjf z$8QVvn-~7P{Q1hb+)MuY>XS2fzk6?Rrhi2J<;Iov%J0fn_xPjlmu`QVH`Lbhx^sQ$ Hqs#vQWTela literal 0 HcmV?d00001 diff --git a/icons/passgen_icon.png b/icons/passgen_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1ed4f77fc1a13b05214e2840b8e34f95ef1de27c GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrl}2EbxddW?X?_wfUrhf=-?;jv*Ss$$$7+cw89V6x8Ar6`du4V8((R z0|w57#f}WFiYHPgsF+C`__S!cvAgURTqAJkD1Qf^yNLNCHXa^^8GX_`yDxYA0-DC) M>FVdQ&MBb@0H)F^m;e9( literal 0 HcmV?d00001 diff --git a/images/preview.png b/images/preview.png new file mode 100644 index 0000000000000000000000000000000000000000..3224b0a8d4209a9fe33daa8596965944ed0bd25a GIT binary patch literal 980 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!3HERU8}DLQjEnx?oJHr&dIz4a#)I;JVQ8u zpoSx*gMop$&eO#)q+-t7x!Fap40u{S+s|&;uh;yy)bfkFx@@mSm1-H2Os(y)%wHtHiJd4`+ZELe? zWBs>B_Li!xv_0@@O4%JLoBV*qWov#1u;;&&QE|HxrmCirW4qw$x9!KmpJuW-tlBbf z$JQ9@oT=|q`{$nV3EisP`D@jwz-rcF{st>f%ha{&SNvI%c`lpzsPxT`ulB!6JD+s@ zw!_aU>8JXaZ2A-Ox3=|%+e9ITsPh-BG?zPu#AP1et#7?!Q(T#@+{@@?>(9+IoaS9G z;^SK{QKlLI9B5!V-SyozB7!rSL zThiTGQFgoPmvJ1hl1eQ-;q{H-RK}vRRN22#zg7Q#n^&{`Z^kp}lLd?svSPe-N7G6V zq&3uR{NutLDSKw(<$Woqcnl6-4EK!t+IQ~dbt&7g;e2P#bk*MyYB=@fp6`|;3$i8mq%JNJS+i;3ng+98{l9t+ z>${6|&+Oa!Ij2u$bNYryD}`*IUYnPwcKUJM>&=Zvcz!Fq2<<%gar5VoOfMS0y?oDv zH*}m88_Iu_SD*iMQMBP);O2GxM@|dhNY?+=XE(c`Fyu^J?BB^7v#%QO=ecBl#>acp ztu3dv-Eua3VWjVO`rf>Koopw)gE~)KX*NE<@iqG9rnmzaAB4;hWIlEK{22o|jm@6_ zLO!u6-=DB{xuimtfw6|wSMJmcZj~Ra)90Mp8+eZ4ldJrX8?RSCXP&imOTXmr6?%W< zosCX*3o2jpni9U_XS6WPM@A&`B#W{(w_adb}A>G zxG{h3@#&(|=7ehV&)>;;rEQb6@>>_Rn?+(bC3H4*u3G%)L>|-Py}>Je+m>8VzISks owun5-*9W%)I2LRKCY#UPeE%I!Bn0%{0Om{vPgg&ebxsLQ07o6q=Kufz literal 0 HcmV?d00001 diff --git a/passgen.c b/passgen.c new file mode 100644 index 0000000..aed4246 --- /dev/null +++ b/passgen.c @@ -0,0 +1,220 @@ +#include +#include +#include +#include +#include +#include +#include + +#define PASSGEN_MAX_LENGTH 16 +#define PASSGEN_CHARACTERS_LENGTH (26*4) + +#define PASSGEN_DIGITS "0123456789" +#define PASSGEN_LETTERS_LOW "abcdefghijklmnopqrstuvwxyz" +#define PASSGEN_LETTERS_UP "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define PASSGEN_SPECIAL "!#$%^&*.-_" + +typedef enum PassGen_Alphabet +{ + Digits = 1, + Lowercase = 2, + + Uppercase = 4, + Special = 8, + + DigitsLower = Digits | Lowercase, + DigitsAllLetters = Digits | Lowercase | Uppercase, + Mixed = DigitsAllLetters | Special +} PassGen_Alphabet; + +const int AlphabetLevels[] = { Digits, Lowercase, DigitsLower, DigitsAllLetters, Mixed }; +const char* AlphabetLevelNames[] = { "1234", "abcd", "ab12", "Ab12", "Ab1#" }; +const int AlphabetLevelsCount = sizeof(AlphabetLevels) / sizeof(int); + +const NotificationSequence PassGen_Alert_vibro = { + &message_vibro_on, + &message_blue_255, + &message_delay_50, + &message_vibro_off, + NULL, +}; + +typedef struct { + FuriMessageQueue* input_queue; + ViewPort* view_port; + Gui* gui; + FuriMutex** mutex; + NotificationApp* notify; + char password[PASSGEN_MAX_LENGTH+1]; + char alphabet[PASSGEN_CHARACTERS_LENGTH+1]; + int length; + int level; +} PassGen; + +void state_free(PassGen* app) { + gui_remove_view_port(app->gui, app->view_port); + furi_record_close(RECORD_GUI); + view_port_free(app->view_port); + furi_message_queue_free(app->input_queue); + furi_mutex_free(app->mutex); + furi_record_close(RECORD_NOTIFICATION); + free(app); +} + +static void input_callback(InputEvent* input_event, void* ctx) { + PassGen* app = ctx; + if(input_event->type == InputTypeShort) { + furi_message_queue_put(app->input_queue, input_event, 0); + } +} + +static void render_callback(Canvas* canvas, void* ctx) { + char str_length[8]; + PassGen* app = ctx; + furi_check(furi_mutex_acquire(app->mutex, FuriWaitForever) == FuriStatusOk); + + canvas_clear(canvas); + canvas_draw_box(canvas, 0, 0, 128, 14); + canvas_set_color(canvas, ColorWhite); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 2, 11, "Password Generator"); + + canvas_set_color(canvas, ColorBlack); + canvas_draw_str_aligned(canvas, 64, 35, AlignCenter, AlignCenter, app->password); + + // Navigation menu: + canvas_set_font(canvas, FontSecondary); + canvas_draw_icon(canvas, 96, 52, &I_Pin_back_arrow_10x8); + canvas_draw_str(canvas, 108, 60, "Exit"); + + canvas_draw_icon(canvas, 54, 52, &I_Vertical_arrow_7x9); + canvas_draw_str(canvas, 64, 60, AlphabetLevelNames[app->level]); + + snprintf(str_length, sizeof(str_length), "Len: %d", app->length); + canvas_draw_icon(canvas, 4, 53, &I_Horizontal_arrow_9x7); + canvas_draw_str(canvas, 15, 60, str_length); + + furi_mutex_release(app->mutex); +} + +void build_alphabet(PassGen* app) +{ + PassGen_Alphabet mode = AlphabetLevels[app->level]; + app->alphabet[0] = '\0'; + if ((mode & Digits) != 0) + strcat(app->alphabet, PASSGEN_DIGITS); + if ((mode & Lowercase) != 0) + strcat(app->alphabet, PASSGEN_LETTERS_LOW); + if ((mode & Uppercase) != 0) + strcat(app->alphabet, PASSGEN_LETTERS_UP); + if ((mode & Special) != 0) + strcat(app->alphabet, PASSGEN_SPECIAL); +} + +PassGen* state_init() { + PassGen* app = malloc(sizeof(PassGen)); + app->length = 8; + app->level = 2; + build_alphabet(app); + app->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + app->view_port = view_port_alloc(); + app->gui = furi_record_open(RECORD_GUI); + app->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + view_port_input_callback_set(app->view_port, input_callback, app); + view_port_draw_callback_set(app->view_port, render_callback, app); + gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); + + app->notify = furi_record_open(RECORD_NOTIFICATION); + + return app; +} + +void generate(PassGen* app) +{ + int hi = strlen(app->alphabet); + for (int i=0; ilength; i++) + { + int x = rand() % hi; + app->password[i]=app->alphabet[x]; + } + app->password[app->length] = '\0'; +} + +void update_password(PassGen* app, bool vibro) +{ + generate(app); + + if (vibro) + notification_message(app->notify, &PassGen_Alert_vibro); + else + notification_message(app->notify, &sequence_blink_blue_100); + view_port_update(app->view_port); +} + +int32_t passgenapp(void) { + PassGen* app = state_init(); + generate(app); + + while(1) { + InputEvent input; + while(furi_message_queue_get(app->input_queue, &input, FuriWaitForever) == FuriStatusOk) { + furi_check(furi_mutex_acquire(app->mutex, FuriWaitForever) == FuriStatusOk); + + if (input.type == InputTypeShort) + { + switch (input.key) { + case InputKeyBack: + furi_mutex_release(app->mutex); + state_free(app); + return 0; + case InputKeyDown: + if (app->level > 0) + { + app->level--; + build_alphabet(app); + update_password(app, false); + } + else + notification_message(app->notify, &sequence_blink_red_100); + break; + case InputKeyUp: + if (app->level < AlphabetLevelsCount - 1) + { + app->level++; + build_alphabet(app); + update_password(app, false); + } + else + notification_message(app->notify, &sequence_blink_red_100); + break; + case InputKeyLeft: + if (app->length > 1) + { + app->length--; + update_password(app, false); + } + else + notification_message(app->notify, &sequence_blink_red_100); + break; + case InputKeyRight: + if (app->length < PASSGEN_MAX_LENGTH) + { + app->length++; + update_password(app, false); + } + else + notification_message(app->notify, &sequence_blink_red_100); + break; + case InputKeyOk: + update_password(app, true); + break; + default: + break; + } + } + furi_mutex_release(app->mutex); + } + } + state_free(app); + return 0; +}